r*****8 发帖数: 2560 | 1 C 语言,初学者问题(3)
char a[] = “abc”;
char * b = “efg”;
程序结束以后,a、b所占的空间会自动释放吗?可查吗?
C 语言的哪个部分会讲到类似问题?
以下是完整程序。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#include
void main() {
char a[] = “abc”;
char * b = “efg”;
printf("n. %s, %s n", a, b);
} |
L***s 发帖数: 1148 | 2 进程结束之后操作系统会回收整个页表。跟C语言无关。 |
r*****8 发帖数: 2560 | 3 如果用malloc,没有free(str)。
等程序结束以后,操作系统也会收回内存空间吗?
char *str;
str = (char *) malloc(15);
free(str);
【在 L***s 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 进程结束之后操作系统会回收整个页表。跟C语言无关。
|
S*A 发帖数: 7142 | 4 进程结束就连进程都被干掉了,进程的使用地址空间当然也就
没有了。
你前面的问题 a[] 是在 stack 分配的,等价于:
char a[4] = { 'a' ,'b', 'c', 0};
【在 r*****8 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 如果用malloc,没有free(str)。 : 等程序结束以后,操作系统也会收回内存空间吗? : char *str; : str = (char *) malloc(15); : free(str);
|
n******n 发帖数: 12088 | 5 也不一定。看a[]在哪里声明的。楼主一开始的例子没有放在函数里
【在 S*A 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 进程结束就连进程都被干掉了,进程的使用地址空间当然也就 : 没有了。 : 你前面的问题 a[] 是在 stack 分配的,等价于: : char a[4] = { 'a' ,'b', 'c', 0};
|
t****t 发帖数: 387 | 6 a is an array on stack.
b is a pointer pointing to some readonly memory, u cannot do things like b[1
] = 'c'
there's no dynamically allocated memory on heap, so there's no need to clean
up memory for either of the case. |
S*A 发帖数: 7142 | 7 人家不是提供了完整的例子吗,我是针对完整的例子说的。
【在 n******n 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 也不一定。看a[]在哪里声明的。楼主一开始的例子没有放在函数里
|
r*****8 发帖数: 2560 | 8 如果free(str); 没写,像以下的例子。
程序运行结束以后,这15字节的内存会遗失吗?
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#include
void main() {
char *str;
str = (char *) malloc(15);
strcpy(str, “abc”);
printf("\n. %s \n", str);
free(str); // 假如这句没写。
} |
G***n 发帖数: 877 | 9 你确定 char * b = “efg”; 可以运行?
没有声明空间memory怎么allocate地址呢? |
G***n 发帖数: 877 | 10 不明白你所谓的丢失是什么意思?如果没有free的话,这个地址空间没有被释放,别的
程序就不能占用,如果你的操作系统不断重复调用这个线程的话,最终memory leak过
大导致系统崩溃。
【在 r*****8 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 如果free(str); 没写,像以下的例子。 : 程序运行结束以后,这15字节的内存会遗失吗? : &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& : #include : void main() { : char *str; : str = (char *) malloc(15); : strcpy(str, “abc”); : printf("\n. %s \n", str); : free(str); // 假如这句没写。
|
|
|
d****n 发帖数: 1637 | 11 bss 段。根本没在heap里,也没在stack
直接读你的binary file,大致在最后面你能看见明文
【在 G***n 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 你确定 char * b = “efg”; 可以运行? : 没有声明空间memory怎么allocate地址呢?
|
n******n 发帖数: 12088 | 12 string literal
【在 G***n 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 你确定 char * b = “efg”; 可以运行? : 没有声明空间memory怎么allocate地址呢?
|
S*A 发帖数: 7142 | 13 程序结束了,那个地址空间的内存就被 OS 回收了。
所谓 malloc 和 free 都是在 virtual address 上的
操作,你整个 VM 都没有了,还占用个啥阿。
直接退出不 free 没有 leak, 也不会导致崩溃。
【在 G***n 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 不明白你所谓的丢失是什么意思?如果没有free的话,这个地址空间没有被释放,别的 : 程序就不能占用,如果你的操作系统不断重复调用这个线程的话,最终memory leak过 : 大导致系统崩溃。
|
r*****8 发帖数: 2560 | 14 可以通过gcc编译没问题,运行几遍没问题。
这个网址说没问题,我对其正确性表示怀疑:
http://c.biancheng.net/cpp/html/81.html
会不会有潜在的问题,我不懂。
特来这里向各位请教。
【在 G***n 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 你确定 char * b = “efg”; 可以运行? : 没有声明空间memory怎么allocate地址呢?
|
G***n 发帖数: 877 | 15 同意链接里的说法。个人认为你没有声明空间,即使能侥幸运行,也会有潜在问题。因
为指针是乱指的,可能会覆盖内存里其他内容,造成程序出错。跟静态数组不同,因为
[]就是内存声明。所以不建议直接指针赋值。
【在 r*****8 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 可以通过gcc编译没问题,运行几遍没问题。 : 这个网址说没问题,我对其正确性表示怀疑: : http://c.biancheng.net/cpp/html/81.html : 会不会有潜在的问题,我不懂。 : 特来这里向各位请教。
|
G***n 发帖数: 877 | 16 恩,确实是这样,没仔细看。针对他这个例子是不会有问题。
不过这样写本身就是个memory leak。当然如果程序不断进入退出是不会对系统造成任
何影响,但如果是程序内部循环调用这种memory leak就有系统崩溃的问题。
【在 S*A 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 程序结束了,那个地址空间的内存就被 OS 回收了。 : 所谓 malloc 和 free 都是在 virtual address 上的 : 操作,你整个 VM 都没有了,还占用个啥阿。 : 直接退出不 free 没有 leak, 也不会导致崩溃。
|
S*A 发帖数: 7142 | 17 你根本不熟悉 C 语言的指针和 string 就不要想当然说了。
这个例子里面没有任何问题。你不要往指针里面直接写就行了。
最多完美一点的是 b 加个 const。
这样的用法多了去了。
【在 G***n 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 同意链接里的说法。个人认为你没有声明空间,即使能侥幸运行,也会有潜在问题。因 : 为指针是乱指的,可能会覆盖内存里其他内容,造成程序出错。跟静态数组不同,因为 : []就是内存声明。所以不建议直接指针赋值。
|
S*A 发帖数: 7142 | 18 谁都知道 memory leak 会有问题,多显然啊。
LZ 问的不是这个,问的是不 free 退出有没有问题。
【在 G***n 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 恩,确实是这样,没仔细看。针对他这个例子是不会有问题。 : 不过这样写本身就是个memory leak。当然如果程序不断进入退出是不会对系统造成任 : 何影响,但如果是程序内部循环调用这种memory leak就有系统崩溃的问题。
|
c******e 发帖数: 545 | 19 这样写没问题,不涉及常规意义上的内存分配释放(堆)
字符串常量都是编译器预分配的,根据体系和实现可能放在.data或者.code段。字符串
常量是静态的,生存周期和程序等同。
char a[] = "abc"
a是在栈上分配的buffer,函数返回就没了,分配本身开销很小(就是改变栈指针),
但是程序需要额外把字符串常量拷贝到a里面。你可以更改a的内容。
char * b = "abc"
b是一个指针(也是栈上的变量),b指向常量字符串。不需要拷贝内容,但是原则上你
不能改变b指向字符串的内容。
你要是感兴趣可以打开编译器的汇编输出看看结果。 |
d****i 发帖数: 4809 | 20 char *b = "abc";
这个string literal应该是在.data segment,.bss segment一般存放uninitialized
static or global variables
【在 d****n 的大作中提到】![](/moin_static193/solenoid/img/up.png) : bss 段。根本没在heap里,也没在stack : 直接读你的binary file,大致在最后面你能看见明文
|
|
|
S*A 发帖数: 7142 | 21 是 .rodata 啦。
这个 “abc” 是 const, 不应该被改变的。
rodata 有可能被 mmap read only。
你试图改变就会 segfault。
【在 d****i 的大作中提到】![](/moin_static193/solenoid/img/up.png) : char *b = "abc"; : 这个string literal应该是在.data segment,.bss segment一般存放uninitialized : static or global variables
|
r*****8 发帖数: 2560 | 22 听各位的讨论比我看书有效多了。
看看我理解对不对,如果在程序中分配的内存,如 str = malloc(15); 如果程序
结束前没有 free(str),没问题。系统会收回内存。
如果程序长时间连续运行(几天、几个月等)重复分配,没有 free(str),这样
系统内存可能全部被占用,有可能死机。
我以上说的对吗? |
r*****8 发帖数: 2560 | 23
各位,有人用过检测memory leak的软件吗?比如我故意分配些大空间 malloc(),
到程序结束故意不 free(),看看系统能不能收回去。
维基百科说到以下软件,有人用过吗,效果如何?
IBM Rational Purify, BoundsChecker, Valgrind, Parasoft Insure++, Dr. Memory
and memwatch are some of the more popular memory debuggers for C and C++
programs.
http://en.wikipedia.org/wiki/Memory_leak |
t****t 发帖数: 387 | 24 所谓memory leak是指程序在运行中一直allocate memory但是没有free,很多软件长时
间运行,这样占用内存越来越大最后会崩溃。
如果一个程序跑一次就正常退出,那中间有点memory leak根本就无所谓。
purify这类的软件能发现你只malloc但没有free的code.
Memory
【在 r*****8 的大作中提到】![](/moin_static193/solenoid/img/up.png) : : 各位,有人用过检测memory leak的软件吗?比如我故意分配些大空间 malloc(), : 到程序结束故意不 free(),看看系统能不能收回去。 : 维基百科说到以下软件,有人用过吗,效果如何? : IBM Rational Purify, BoundsChecker, Valgrind, Parasoft Insure++, Dr. Memory : and memwatch are some of the more popular memory debuggers for C and C++ : programs. : http://en.wikipedia.org/wiki/Memory_leak
|
l****c 发帖数: 838 | 25 http://valgrind.org/
main() is a function, program entry point.
If malloc memory in main, and do not free at the code,
the memory is freed after the program exits,the process
or thread is finished. The OS reclaims the resources.
But if this function is NOT main
and the function is called many times, it leaks memory.
You need to learn to program safely, defensively.
In a typical software, there is so many functions.
Each function can have multiple possible exit point.
So if you are not careful, you can easily leak memory.
Few program simply runs from main to end and exit.
Why learn C? It is not easy although it seems simple.
Java, C# and many dynamic languages manage memory automatically.
Even C++ has smart pointers to make programming easier.
Unless you do embedded system programming (I do), C is not
the language of choice.
You have a long way to go to be a programmer.
Memory
【在 r*****8 的大作中提到】![](/moin_static193/solenoid/img/up.png) : : 各位,有人用过检测memory leak的软件吗?比如我故意分配些大空间 malloc(), : 到程序结束故意不 free(),看看系统能不能收回去。 : 维基百科说到以下软件,有人用过吗,效果如何? : IBM Rational Purify, BoundsChecker, Valgrind, Parasoft Insure++, Dr. Memory : and memwatch are some of the more popular memory debuggers for C and C++ : programs. : http://en.wikipedia.org/wiki/Memory_leak
|
G***n 发帖数: 877 | 26 Good point. Memory leak can happen even you free the memory correctly in
your code, the function could exit before the free function is called.
Programming in good style is important in C.
【在 l****c 的大作中提到】![](/moin_static193/solenoid/img/up.png) : http://valgrind.org/ : main() is a function, program entry point. : If malloc memory in main, and do not free at the code, : the memory is freed after the program exits,the process : or thread is finished. The OS reclaims the resources. : But if this function is NOT main : and the function is called many times, it leaks memory. : You need to learn to program safely, defensively. : In a typical software, there is so many functions. : Each function can have multiple possible exit point.
|
d****n 发帖数: 1637 | 27 你好好练习malloc and free。C 就那么点东西都在这俩函数里呢。
不会死机,现在的OS不会因为oom死机,(你的程序)一般就core dump了,或者直接
crash。
【在 r*****8 的大作中提到】![](/moin_static193/solenoid/img/up.png) : : 各位,有人用过检测memory leak的软件吗?比如我故意分配些大空间 malloc(), : 到程序结束故意不 free(),看看系统能不能收回去。 : 维基百科说到以下软件,有人用过吗,效果如何? : IBM Rational Purify, BoundsChecker, Valgrind, Parasoft Insure++, Dr. Memory : and memwatch are some of the more popular memory debuggers for C and C++ : programs. : http://en.wikipedia.org/wiki/Memory_leak
|
r*****8 发帖数: 2560 | 28 各位的回答太好了,非常感谢!
我回去好好消化一下。
再次感谢! |
r*****8 发帖数: 2560 | 29 我要把一台仪器接到(串行口)单片机上。半年到一年无人看管。
这台单片机只能运行2种语言,其中一种是 C。
我就上网看了一下 C,发现很难。
不过我的所有程序都通了,需要按各位高手指点的方向,优化一下。 |
c******e 发帖数: 545 | 30 单片机如无特别必要就别用啥malloc/free了,都开全局变量就行了。 |
|
|
d****i 发帖数: 4809 | 31 exactly
【在 c******e 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 单片机如无特别必要就别用啥malloc/free了,都开全局变量就行了。
|
r*****8 发帖数: 2560 | 32 程序结束以后,全局变量所占的内存都会被收回是吗?
【在 c******e 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 单片机如无特别必要就别用啥malloc/free了,都开全局变量就行了。
|
c******e 发帖数: 545 | 33 那看你多复杂的单片机了。相当多的单片机系统没有操作系统,程序循环从来不退出的
。稍微复杂点儿的跑轻量级操作系统,也只在线程级别而已,也不涉及程序结束返回的
问题。再复杂点的就是跑Linux之类的了,看情况吧,没有MMU的可能会有点儿问题。 |
S*A 发帖数: 7142 | 34 不会。是固定分配。
单片机程序一般不会结束,里面通常有个永远的
循环。最多中间 sleep 休眠或者完全关机。
【在 r*****8 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 程序结束以后,全局变量所占的内存都会被收回是吗?
|
r*****8 发帖数: 2560 | 35 我的程序每隔0.5 - 2小时运行一次。
那么,同一个全程变量,每次运行会用同一个内存地址吗?
我用的单片机是PC104,内核是486或者ARM,系统是Linex。
【在 S*A 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 不会。是固定分配。 : 单片机程序一般不会结束,里面通常有个永远的 : 循环。最多中间 sleep 休眠或者完全关机。
|
r*****8 发帖数: 2560 | 36 我的程序每隔0.5 - 2小时运行一次,要求一年以上无人看管。
我用的单片机是PC104,内核是486或者ARM,系统是Linex。
那么,同一个全程变量,每次运行会用同一个内存地址吗?
还是每次用一个新的内存地址?
【在 c******e 的大作中提到】![](/moin_static193/solenoid/img/up.png) : 那看你多复杂的单片机了。相当多的单片机系统没有操作系统,程序循环从来不退出的 : 。稍微复杂点儿的跑轻量级操作系统,也只在线程级别而已,也不涉及程序结束返回的 : 问题。再复杂点的就是跑Linux之类的了,看情况吧,没有MMU的可能会有点儿问题。
|