忽然发现最基础的都忘了:函数外可以做什么事情?

seai 2012-09-04 11:03:55
/*linux c main.c*/
#include <stdio.h>
/*
这里可以做什么事?可以写任何代码?那它们在何时执行?
printf("试试看!\n");
如果这是一个.so共享库呢,在共享库中,函数外也可以写任何代码?那它们在何时执行?
/*
int main(void)
{
printf("随便玩的!\n");
}

问题是由一个在多线程环境中被调用的so共享库引出的:
因为要在多线程环境中使用,为了保证其中的函数线程安全,我使用到了pthread_mutex_t、pthread_key_t,但pthread_mutex_t和pthread_key_t本应该在主线程中一次初始化的,我不确定在函数外这样写,是否正确。。。。。。
/*myfuns.c*/
static pthread_key_t key;
pthread_key_create (&key, NULL);//pthread_key_delete(key);又该写在哪呢?
/*其他全局变量*/
/*my_fun被线程调用*/
void my_fun(){
/*这里访问了全局变量*/
}
...全文
550 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
seai 2012-09-06
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 的回复:]

非常感谢楼上这么多朋友的解答。

现在可以这样理解:

函数外的语句,其实是编译阶段能够做的事情才有效,比如声明函数、定义变量、甚至是初始化变量,不论是否动态库中,都是这个道理;但如果那些非编译阶段不能确定的工作便不能在函数外做?
[/Quote]

说的就是linux C。
www_adintr_com 2012-09-06
  • 打赏
  • 举报
回复
函数外初始变量为随机数
在 C++ 中是可以的, 在 C 中不行.
seai 2012-09-06
  • 打赏
  • 举报
回复
非常感谢楼上这么多朋友的解答。

现在可以这样理解:

函数外的语句,其实是编译阶段能够做的事情才有效,比如声明函数、定义变量、甚至是初始化变量,不论是否动态库中,都是这个道理;但如果那些非编译阶段不能确定的工作便不能在函数外做,比如初始变量为随机数?
ForestDB 2012-09-05
  • 打赏
  • 举报
回复
函数外能定义函数和全局变量,仅此而已。
注意是定义。
seai 2012-09-05
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 的回复:]

malloc_usable_size() returns the number of bytes available in the
dynamically allocated buffer ptr, which may be greater than the
requested size (but is guaranteed ……
[/Quote]

看不到中文就看代码。第一个元素是int*,后面五个元素是char*,各元素所占用长度不一致。


#include<stdio.h>
#include<stdlib.h>
int main(){
void ** p1 = NULL;
p1 = (void **)malloc(sizeof(int*)+sizeof(char *) * 5);//在不了解如何malloc的情况下,有可能正确的访问里面的数据吗?//第一个元素是int*,后面五个元素是char*。
char *s="12333";
p1[0]=s;p1[1]=s;p1[2]="34444444";
char * p2[] = {"aaaaa","bbbbb","cccccccc"};
printf("%d %d",malloc_usable_size(p1),malloc_usable_size(p1)/sizeof(char*));//28 7
return 0;
}
DataChat.Club 2012-09-05
  • 打赏
  • 举报
回复
malloc_usable_size() returns the number of bytes available in the
dynamically allocated buffer ptr, which may be greater than the
requested size
(but is guaranteed to be at least as large, if the
request was successful). Typically, you should store the requested
allocation size rather than use this function
.


这句看不懂:但如果是非对齐的子指针,不知道如何...

[Quote=引用 18 楼 的回复:]

找到malloc_usable_size似乎可以到达某些目的,比如:

#include<stdio.h>
#include<stdlib.h>
int main(){
void ** p1 = NULL;
p1 = (void **)malloc(sizeof(char *) * 5);
char *s="12333";
p1[0]=s;p1[1]=s;p1[2]="34444……
[/Quote]
DataChat.Club 2012-09-05
  • 打赏
  • 举报
回复
sizeof(int *)和sizeof(char*)是相等的,同一台机器上无论如何都是相等的,你为什么加“即使”两个字?

不信?你可以做个实验再说嘛:

printf("%d, %d, %d",sizeof(int *), sizeof(char *), sizeof(int *) == sizeof(char *));

你的程序里:

p1 = (void **)malloc(sizeof(int*)+sizeof(char *) * 5);

在你的电脑上就是(32位机,sizeof(指针类型) = 4):

p1 = (void **)malloc(24)

p1申请了24字节的内存。

你的实验:printf("%d %d",malloc_usable_size(p1),malloc_usable_size(p1)/sizeof(char*));

实际上是:printf("%d %d",malloc_usable_size(p1),malloc_usable_size(p1)/4);

打印结果:28 7

p1明明只申请了24字节的内存,但malloc_usable_size(p1)却是28.

你的实验不能说明int* 和 char* 的长度关系。

你的实验只能说明:malloc_usable_size() returns the number of bytes available in the dynamically allocated buffer ptr, which may be greater than the requested size..

你能用心点看#22楼的英文吗?

"int *是4字节,char *也是4字节" --你的理解力足够理解这句话了吗?

[Quote=引用 28 楼 的回复:]

引用 26 楼 的回复:

是一样的。
引用 24 楼 的回复:

int *是4字节,char *也是4字节,什么长度不一样了?

引用 23 楼 的回复:

引用 22 楼 的回复:

malloc_usable_size() returns the number of bytes available in the
dynamically allo……
[/Quote]
franzhong 2012-09-05
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

引用 3 楼 的回复:

引用 2 楼 的回复:

1.函数外就不要写定义初始化意外的执行语句了。

2.除了定义初始化 否则函数调用语句也放到函数体里面


是建议不要写,还是写了直接语法错误呢?回到最初的问题,如果执行语句,会发生什么?

而且“定义初始化”的概念是什么,“int i=getvalue();”通过调用另一函数取初始化,也算初始化吧,但这样不还是执行了……
[/Quote]
就这个理,防各种意外
www_adintr_com 2012-09-05
  • 打赏
  • 举报
回复
我没有使用过也没有见过专门来维护这些信息而设计的内存分配函数或是库什么的.
专用的内存分配器都是在考虑如何提高内存分配的效率, 以及减少内存碎片上.
关键在于, 维护这些信息其实并不会为程序带来多大的负担, 如果你不使用这些信息, 不去维护也无所谓的.
现在设计的库函数或是 API, 如果接受指针参数来表示多个元素, 都会让你把长度传递进去, 即使你有一些维护指针长度的系统, 它们也不会去使用的.
seai 2012-09-05
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 的回复:]

1. 函数外不能出现除定义外的其他语句.
2. int i=getvalue(); 或者其他带有构造函数的类型的全局变量, 他们都是有 CRT 库来初始化的. 也就是你可执行文件的入口点其实并不是 main, 而是在库里面的. 它们会在调用 main 之前调用初始化全局变量的函数.
3. char **str={"aaaaa","bbbbb","cccccccc"}; 数组退化成指针时类型信……
[/Quote]


我可以这样理解:一句话,自行分配的内存,应该自行管理,包括大小、类型、指针数量等等信息,可能都需要自己做一个而外的纪录,来帮助程序的运行,没有现成的函数获取这些信息??
www_adintr_com 2012-09-05
  • 打赏
  • 举报
回复
1. 函数外不能出现除定义外的其他语句.
2. int i=getvalue(); 或者其他带有构造函数的类型的全局变量, 他们都是有 CRT 库来初始化的. 也就是你可执行文件的入口点其实并不是 main, 而是在库里面的. 它们会在调用 main 之前调用初始化全局变量的函数.
3. char **str={"aaaaa","bbbbb","cccccccc"}; 数组退化成指针时类型信息已经丢失. 而指针指向的数据大小是无法获取的. 要不然字符串也没有必要使用 '\0' 来结尾了. 能直接获取 char* 的元素个数的话还用得着写一个需要循环的 strlen 来获取字符串的大小吗?
4. malloc 出来的内存由于会在里面放一些内存管理的信息, 你或许可以取得它分配的内存大小. 但也不是一种获得指针大小的方法. malloc_usable_size 函数里也说了, 你应该自己维护你分配的大小, 而不是使用这个函数.
seai 2012-09-05
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 的回复:]

是一样的。
引用 24 楼 的回复:

int *是4字节,char *也是4字节,什么长度不一样了?

引用 23 楼 的回复:

引用 22 楼 的回复:

malloc_usable_size() returns the number of bytes available in the
dynamically allocated buffer pt……
[/Quote]

你能做完实验再说吗?我已经打出结果了:
printf("%d %d",malloc_usable_size(p1),malloc_usable_size(p1)/sizeof(char*));//28 7
能用心点看吗?

再说了,即使int*和char*是一样长,但世界上还就所有类型都一样了,或许我举的例子不好,但我只是说明如果存在长度不一样时该怎么办吧?

什么理解力。。。。。。。。。。。。。
AndyZhang 2012-09-05
  • 打赏
  • 举报
回复
不要放在外面了,不行滴
didijiji 2012-09-05
  • 打赏
  • 举报
回复
是一样的。
[Quote=引用 24 楼 的回复:]

int *是4字节,char *也是4字节,什么长度不一样了?

引用 23 楼 的回复:

引用 22 楼 的回复:

malloc_usable_size() returns the number of bytes available in the
dynamically allocated buffer ptr, which may be grea……
[/Quote]
康斯坦汀 2012-09-05
  • 打赏
  • 举报
回复
函数外的语句不能被异常处理机制捕获,一旦出意想不到的问题,程序就会崩溃。
DataChat.Club 2012-09-05
  • 打赏
  • 举报
回复
int *是4字节,char *也是4字节,什么长度不一样了?

[Quote=引用 23 楼 的回复:]

引用 22 楼 的回复:

malloc_usable_size() returns the number of bytes available in the
dynamically allocated buffer ptr, which may be greater than the
requested size (but is guarantee……
[/Quote]
seai 2012-09-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

1.函数外就不要写定义初始化意外的执行语句了。

2.除了定义初始化 否则函数调用语句也放到函数体里面
[/Quote]

是建议不要写,还是写了直接语法错误呢?回到最初的问题,如果执行语句,会发生什么?

而且“定义初始化”的概念是什么,“int i=getvalue();”通过调用另一函数取初始化,也算初始化吧,但这样不还是执行了所谓的“语句”么?
pengzhixi 2012-09-04
  • 打赏
  • 举报
回复
1.函数外就不要写定义初始化意外的执行语句了。

2.除了定义初始化 否则函数调用语句也放到函数体里面
图灵狗 2012-09-04
  • 打赏
  • 举报
回复
天外飞仙!
MadMarks 2012-09-04
  • 打赏
  • 举报
回复
好想忘掉的太多了吧....
加载更多回复(17)

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧