我被告知在初始化像这样的字符串时
char str[] = "Hello world!";
编译器将在常量内存中分配一个区域(只读程序),然后将字符串复制到驻留在堆栈中的数组。我的问题是,在修改我给出的副本后,我可以阅读或指向原始字符串,以及如何?如果没有,为什么字符串甚至首先存在于堆栈之外?
答案 0 :(得分:1)
这样做是为了提高空间效率。当你写:
char str[] = "Hello world!";
它有效地编译,就像你写的那样:
static char str_init[] = "Hello world!";
char str[13];
strncpy(str, str_init, 13);
实现此目的的另一种方法可能等同于:
char str[13];
str[0] = 'H';
str[1] = 'e';
...
str[11] = '!';
str[12] = 0;
但对于长串,这是非常低效的。对于每个字符的字符,它将使用完整的指令字(可能是4个字节,但在某些体系结构上可能更多),而不是字符串的每个字符的1个字节的静态数据。这将不必要地使初始化数据的大小翻两番。
答案 1 :(得分:0)
因为程序必须记住某处的字符串,即你所谓的“常量记忆”。否则,在分配变量时,如何知道要分配的值?考虑具有给定初始值的变量。在声明之前不会分配变量。但是初始值必须存储在其他地方。
答案 2 :(得分:0)
当程序运行时," Hello world"将作为字符串文字存储在内存的常量部分中,之后,程序将在堆栈中保留足够的空间,并从内存的常量部分逐字符复制。遗憾的是,您无法访问存储字符串文字的常量部分,因为您告诉程序您希望值可修改(字符串存储在堆栈中),因此它会提供您所要求的内容。
答案 3 :(得分:0)
编译此语句时
char str[] = "Hello world!";
编译器不会将字符串文字保留在程序中。它仅用于初始化数组。
如果你想保留字符串文字,那么你必须写下以下方式
char *s = "Hello world!";
char str[13];
strcpy( str, s );
答案 4 :(得分:0)
您的大部分问题已在其他答案中得到解决,但是,我没有看到有人专门解决这个问题:
关于你的问题: ...我可以在修改我给出的副本之后读取或指向原始字符串,以及如何?
以下序列演示了如何在修改副本后 阅读原文 :
char str[] = "hello world"; //creates original (stack memory)
char *str2 = 0;//create a pointer (pointer created, no memory allocated)
str2 = StrDup(str); populate pointer with original (memory allocated on heap)
str2[5]=0; //edit copy: results in "hello" (i.e. modified) (modifying a location on the heap)
str; //still contains "hello world" (viewing value on the stack)
编辑 (回答评论问题)
上面的答案 仅解决了在修改副本后访问原始字符串的具体问题。我刚刚展示了一套可能的步骤来解决这个问题。您也可以编辑原始字符串:
char str [] =“Hello world!”; //在堆栈内存中创建名为“str”的位置,
//并为文字字符串分配足够的空间:
//“Hello world!”,共有13个空格(包括\ 0)
strcpy(str,“new string”); //用“new string”替换原始内容
//旧内容不再可用。
因此,使用这些步骤,变量str
中的原始值将更改,并且不再可用。
我在原始答案中概述的方法(在顶部)显示了可以制作可编辑副本的方式,同时保留原始变量。
在您的评论问题 中,您指的是诸如系统内存和常量内存之类的内容。通常,系统存储器指的是系统上的RAM实现(即物理存储器的数量)。通过常量内存,我的猜测是你指的是在堆栈上创建的变量使用的内存。 (继续阅读)
首先 在开发或运行时环境中,有堆栈内存。这通常默认为某个最大值,例如250,000字节。它是大多数开发环境中的预构建可设置值,可供您在堆栈上创建的任何变量 使用。示例:
int x[10]; //creates a variable on the stack
//using enough memory space for 10 integers.
int y = 1; //same here, except uses memory for only 1 integer value
第二 还有一种称为堆的内存。堆内存量取决于系统,系统可用的物理内存越多,可用于应用程序中可变内存空间的堆内存就越多。 动态分配内存时使用堆内存,例如使用malloc()
,calloc()
,realloc()
。
int *x=0; //creates a pointer, no memory allocation yet...
x = malloc(10); //allocates enough memory for 10 integers, but the
//memory allocated is from the _heap_
//and must be freed for use by the system
//when you are done with it.
free(x);
我已经标记了原始帖子(上图),并显示了每个变量使用的内存类型。我希望这会有所帮助。