我正在尝试了解 C 的内存管理。到目前为止,我已经有了一个清晰的概述,但有一个问题对我来说并不是那么明显。
如果我声明一个
char
指针并为其分配一些字符串,则该指针包含该字符串的地址(在某处分配)。
char *pchar1 = "Hello World OLD";
unsigned long x = (unsigned long)pchar1; //Note that I'm storing the value of this addr for further usage
printf("pchar1 content: %s\n", pchar1); // Hello World OLD
printf("Adress of pchar1: %lu\n\n", pchar1); //<Some Random Addr>
如果我将另一个字符串分配给指针,那么它会指向另一个地址。
pchar1 = "Hello World NEW";
printf("pchar1 content: %s\n", pchar1); // Hello World NEW
printf("Adress of pchar1: %lu\n\n", pchar1); // <A different addrs than the fisrt one>
如果我尝试读取旧的内存位置,我发现仍然有我的旧字符串
printf("Old addr stores in 'x': %lu\n", x); // Hello World OLD
printf("Reading old pchar1 mem addr (from x): %s\n\n", (char *)x); // <The First Address>
我的问题是,由于使用的内存没有被释放,如果我不存储旧内存地址的值,那么我失去了它的踪迹,这样的事情可能会导致溢出吗?
while(1){
pchar1 = "Hello World OLD"; //Stores this string in a different addres
pchar1 = "Hello World NEW"; //Stores this string in a different addres
}
以下是整个代码:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
char *pchar1 = "Hello World OLD";
unsigned long x = (unsigned long)pchar1;
printf("pchar1 content: %s\n", pchar1);
printf("Adress of pchar1: %lu\n\n", pchar1);
pchar1 = "Hello World NEW";
printf("pchar1 content: %s\n", pchar1);
printf("Adress of pchar1: %lu\n\n", pchar1);
printf("Old addr stores in 'x': %lu\n", x);
printf("Reading old pchar1 mem addr (from x): %s\n\n", (char *)x);
//Overflow?
while(1){
pchar1 = "Hello World OLD"; //Stores this string in a different addres
pchar1 = "Hello World NEW"; //Stores this string in a different addres
}
printf("\nSuccess!...\n");
return 0;
}
提前致谢!
字符串常量通常存储在程序内存的静态只读部分中。这些常量在程序的整个生命周期中都可用,无论您是否保留指向它们的指针。
此外,如果一个字符串常量在程序中出现多次,则每个实例引用同一块内存的情况并不少见。
在这个特殊情况下:
while(1){
pchar1 = "Hello World OLD"; //Stores this string in a different addres
pchar1 = "Hello World NEW"; //Stores this string in a different addres
}
您有两个字符串常量存储在该只读内存段中。在循环的每次迭代中,
pchar1
都会被修改为指向这些字符串常量之一。所以它并没有创建更多正在使用的内存。
另一方面,如果你有这样的事情:
void foo(void)
{
char s[] = "Some very very very long string";
foo();
}
当你调用
foo
时,堆栈上会有一个数组,每次函数迭代时都会存储一次字符串"Some very very very long string"
,最终你会耗尽堆栈空间,s
越大速度越快那将会发生。