I. char *str = "Stack";
II. char *str = (char*) malloc(6);
strcpy(str, "Stack");
上述两种方法有何区别?
窗帘后面是相同还是不同?
答案 0 :(得分:19)
上面的代码会导致问题。
第一个实例称为静态字符串分配和定义。
对于像int
等常规变量和非字符串数据类型,这样的声明将在堆栈上分配数据。在通过字符串文字初始化字符串的情况下(即:"stack"
),它被分配在内存的只读部分。
不应修改字符串本身,因为它将存储在内存的只读部分中。指针本身可以更改为指向新位置。
即:
char strGlobal[10] = "Global";
int main(void) {
char* str = "Stack";
char* st2 = "NewStack";
str = str2; // OK
strcpy(str, str2); // Will crash
}
为安全起见,您应该实际分配为const数据的指针,即:
const char* str = "Stack"; // Same effect as char* str, but the compiler
// now provides additional warnings against doing something dangerous
第二种称为动态分配,它在堆上分配内存,而不是堆栈。可以毫不费力地修改字符串。在某些时候,您需要通过free()
命令释放此动态分配的内存。
第三种方法是分配字符串,这是堆栈上的静态分配。这允许您修改保存字符串的数组的内容,并且它是静态分配的。
char str[] = "Stack";
总结:
Example: Allocation Type: Read/Write: Storage Location:
================================================================================
const char* str = "Stack"; Static Read-only Code segment
char* str = "Stack"; Static Read-only Code segment
char* str = malloc(...); Dynamic Read-write Heap
char str[] = "Stack"; Static Read-write Stack
char strGlobal[10] = "Global"; Static Read-write Data Segment (R/W)
您还应该了解如何为现代操作系统中的应用程序分割数据。它将真正增加您对代码构建方式的理解。
<强>参考强>
<http://en.wikipedia.org/wiki/Data_segment>
<http://en.wikipedia.org/wiki/Code_segment>
答案 1 :(得分:2)
在第一种情况下,指针指向一个const char*
,它在过程存储器的只读部分中分配。
在第二种情况下,您将动态分配内存,并且eventuall将字符串“Stack”复制到您分配的内存中。
您最终必须使用free
从 II 释放内存。
答案 2 :(得分:0)
忘记其他声明存储内部堆栈的答案,因为它们不正确。(现在已经删除了那些答案..)
case I:
你有一个指针str
指向只读内存区域(.rodata
部分),其内容为"Stack"
case II:
你有一个指针str
,它指向一个动态分配的区域(在堆中),其内容为"Stack"
,可以修改并且可以通过调用{{1}来释放使用它之后。