关于C#:声明的字符串和分配的字符串之间的区别


Difference between declared string and allocated string

1
2
3
4
I.  char *str ="Stack";

II. char *str = (char*) malloc(6);
    strcpy(str,"Stack");

上述两种方法有什么区别?

窗帘后面是相同的还是不同的?


上述代码将导致问题。

第一个实例称为静态字符串分配和定义。对于像int等普通变量和非字符串数据类型,这样的声明将在堆栈上分配数据。如果字符串是通过字符串文本(例如:"stack"初始化的),则会在内存的只读部分分配该字符串。

不应修改字符串本身,因为它将存储在内存的只读部分中。指针本身可以更改为指向新位置。

IE:

1
2
3
4
5
6
7
8
char strGlobal[10] ="Global";

int main(void) {
  char* str ="Stack";
  char* st2 ="NewStack";
  str = str2;  // OK
  strcpy(str, str2); // Will crash
}

为了安全起见,实际上应该将其分配为指向常量数据的指针,即:

1
2
const char* str ="Stack"; // Same effect as char* str, but the compiler
                           // now provides additional warnings against doing something dangerous

第二种是动态分配,它在堆上分配内存,而不是堆栈。可以修改字符串而不需要麻烦。在某些时候,您需要通过free()命令释放动态分配的内存。

第三种分配字符串的方法是在堆栈上进行静态分配。这允许您修改保存字符串的数组的内容,并且它是静态分配的。

1
char str[] ="Stack";

综上所述:

1
2
3
4
5
6
7
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)

您还应该了解如何为现代操作系统中的应用程序分割数据。它将真正提高您对代码构建方式的理解。

工具书类

  • 数据段,访问日期2013-04-15,
  • 代码段,访问日期2013-04-15,

  • 在第一种情况下,指针指向分配在进程内存只读部分的const char*。在第二种情况下,您将动态地分配内存,并将字符串"stack"复制到分配的内存中。

    您最终必须使用free从ii释放内存。


    忘记其他的答案,因为它们是错误的,所以它们声称任何关于存储在堆栈中的东西。(噢,现在那些答案被删除了。)

    case I:有一个指针str指向一个只读内存区域(.rodata部分),其内容为"stack"

    case II:您有一个指针str指向一个动态分配的区域(在堆中),该区域的内容是"stack",它是可修改的,并且在使用后通过调用free(str)释放。