C中的字符串和指针

Lok*_*esh 4 c memory string malloc pointers

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
        char* a = malloc(5 * sizeof(char));
        a = "1";
        free(a);
}
Run Code Online (Sandbox Code Playgroud)

关于上面的代码我有两个问题:

  1. 当我初始化这样的代码时,为什么代码会给free(a)带来错误:

a ="1"

并且当我初始化这样的时候不会给free(a)带来任何错误:

a [0] ='1'.

  1. 当我用[0] ='1'初始化a并使用printf("%s",a)打印字符串a为什么我得到结果

    '1'

没有用'\ 0'声明第二个索引?

Dav*_*nan 11

有规则的malloc自由是你必须只传递给释放,是由一个呼叫分配给指针的malloc(或像它的等价物之一的realloc释放calloc).你不这样做:

char* a = malloc(5 * sizeof(char));
a = "1";
free(a);
Run Code Online (Sandbox Code Playgroud)

当你打电话给free,你传递一个没有通过调用malloc分配的.这会导致您的程序具有未定义的行为.


你理解的问题是我怀疑你不明白a ="1"是做什么.

我怀疑你想象这会将字符串复制到你分配的内存中.它将指针a更改为指向不同的地址.

实际上,通过分配a而不是它指向的内存,你正在泄漏分配的内存.您的代码完全类似于:

int i = 1;
i = 2;
Run Code Online (Sandbox Code Playgroud)

我相信你可以看到i的初始化是没有意义的,因为你立即用新值覆盖i的值.这正是你用指针做的.


您可以复制字符串strcpy.像这样:

char* a = malloc(5 * sizeof(char));
strcpy(a, "1");
free(a);
Run Code Online (Sandbox Code Playgroud)

同样,当你写作

char* a = malloc(5 * sizeof(char));
a[0] = '1';
printf("%s", a);
free(a);
Run Code Online (Sandbox Code Playgroud)

您正在分配调用malloc所分配的缓冲区的内容.因此呼叫free是正确的.

但是,当您这样做时,字符串不一定以空值终止.您发现您的printf似乎有效,但这只是偶然的.

a [1]的内容是不明确的,似乎偶然的,[1]在运行程序时确实包含null.

这就是您通常使用strcpy之类的字符串函数来执行复制并确保空终止的原因.你当然需要注意不要超出你的缓冲区.


最后,根据定义,sizeof(char)== 1所以你可以像这样编写malloc:

char* a = malloc(5);
Run Code Online (Sandbox Code Playgroud)