声明string和分配string之间的区别
I. char *str = "Stack"; II. char *str = (char*) malloc(6); strcpy(str, "Stack");
上述两种方法有什么区别?
窗帘背后是否相同或不同?
上面的代码会导致问题。
第一个实例称为静态string分配和定义。 对于像int
等常规variables和非string数据types,这样的声明将在堆栈上分配数据。 在通过string文字(即: "stack"
)初始化string的情况下,它被分配在内存的只读部分。
string本身不应该被修改,因为它将被存储在内存的只读部分。 指针本身可以改变指向一个新的位置。
即:
char strGlobal[10] = "Global"; int main(void) { char* str = "Stack"; char* st2 = "NewStack"; str = str2; // OK strcpy(str, str2); // Will crash }
为了安全起见,你应该实际上分配一个指向常量数据的指针,即:
const char* str = "Stack"; // Same effect as char* str, but the compiler // now provides additional warnings against doing something dangerous
第二个被称为dynamic分配,它在堆上分配内存,而不是堆栈。 string可以修改而不麻烦。 在某些时候,你需要通过free()
命令释放这个dynamic分配的内存。
还有第三种方法来分配一个string,这个string是堆栈上的静态分配。 这允许你修改数组的内容,这个数组是静态分配的。
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)
您还应该了解现代操作系统中应用程序的数据分段方式。 这将真正增加您对代码的构build方式的理解。
参考
- 数据段 ,访问2013-04-15,
<http://en.wikipedia.org/wiki/Data_segment>
- 代码段 ,访问2013-04-15,
<http://en.wikipedia.org/wiki/Code_segment>
在第一种情况下,你的指针指向在进程内存的只读部分中分配的const char*
。
在第二种情况下,您正在dynamic分配内存,并且事件会将string“Stack”复制到您分配的内存中。
你最终必须free
使用II来释放内存。
忘记其他答案,声称任何有关存储内部堆栈,因为他们是不正确的。 (哦,现在这些答案已被删除..)
case I:
你有一个指向str
的内容是"Stack"
的只读内存区域( .rodata
节)的指针str
。
case II:
你有一个指向str
的指针str
指向一个dynamic分配的区域(在堆中),其内容是"Stack"
,它是可以修改的,并且在使用之后通过自由调用free(str)
来释放。