内存分配如何与字符指针(字符串文字、数组)一起使用?

かわい*_*いそu 2 c pointers char-pointer

目前正在阅读 K&R,刚刚偶然发现了 char 指针。rn这本书里没有提到定义char指针时的内存分配,也许后面会解释。但这没有意义,所以我正在寻求帮助:)

1

// No errors
char *name;
char *altname;
strcpy(altname,name);
Run Code Online (Sandbox Code Playgroud)

2

// No errors, internals of *name have been successfully moved to *altname
char *name = "HI";
char *altname;
strcpy(altname, name);
Run Code Online (Sandbox Code Playgroud)

3

// Segmentation fault, regardless of how I define *altname
char *name = "HI";
char *altname = "randomstring";
strcpy(altname, name);
Run Code Online (Sandbox Code Playgroud)

4

// Segmentation fault, regardless of how I define *altname
char *name;
char *altname = "     ";
strcpy(altname, name);
Run Code Online (Sandbox Code Playgroud)

5

// copies internals of *name only if size of char s[] > 8???
char s[9];
char n[] = {'c', 'b'};
char *name = n;
char *altname = s;
strcpy(altname, name);
Run Code Online (Sandbox Code Playgroud)

即使没有分配内存,为什么第一个示例不会产生错误?

为什么第二个成功地将 name 复制到 altname,即使没有为 altname 分配内存;

为什么第三个和第四个核心转储?

为什么第五个要求 s 的大小 >8?

Dan*_*ker 5

I'm a bit surprised that the first two examples worked. strcpy takes the character array pointed to by the second argument and copies it to the character array pointed to by the first argument.

In your first example, the pointers name and altname aren't pointing to anything. They're uninitialized pointers. Now they have some value based on either whatever gunk was in memory when the main function was executed or just however the compiler decided to initialize them. That's why I'm surprised that your code isn't crashing.

无论如何,您的第三个示例出现段错误的原因是您已将两个指针设置为指向字符串文字(即"HI""randomstring")。字符串文字(很可能)存储在内存的只读部分中。因此,当您将strcpy目标指针设置为时altname,您将尝试写入只读内存。这是对内存的无效使用,从而导致崩溃。你的第四个例子也是如此。

在最后一个示例中,您的问题是n不是以空终止。 strcpy不断复制字符,直到到达终止符(即'\0')。您已将 a'c'和 a放入'b'数组中,但没有终止符。因此,strcpy即使到达 的末尾,也会继续复制nsizeof(s)它在大于 8时起作用的事实可能涉及堆栈上恰好存在空字节的位置。也就是说,如果你设置s得太小,你就会写到它的末尾并损坏堆栈上的内存。当函数执行完毕时,您可能会覆盖返回指针,从而返回到某个无效的内存地址。

您需要做的是,不要使用指针,而是使用数组。这将为您提供内存可写部分所需的存储空间。您还需要确保您的数组以空终止。这可以通过使用字符串初始化数组来自动完成。

char name[] = "HI";
char altname[] = "randomstring";
strcpy(altname, name);
Run Code Online (Sandbox Code Playgroud)
char s[3]; // Enough space to hold "cb" plus a null-terminator.
char n[] = "cb";
char *name = n;
char *altname = s;
strcpy(altname, name);
Run Code Online (Sandbox Code Playgroud)