将内存分配给char* C语言

8
这是分配内存给 char* 的正确方式吗?
char* sides ="5";

char* tempSides;

tempSides = (char*)malloc(strlen(inSides) * sizeof(char));

@brickner 这个在strlen函数中怎么处理呢?strlen(inSides) + 1 - boom
7个回答

18
几乎正确。字符串以NUL结尾,因此您可能需要分配一个额外的字节来存储NUL字节。也就是说,即使sides只有1个字符长,它实际上是2个字节:{5'\0'}。

所以正确的方式应该是:

tempSides = (char *)malloc((strlen(sides)+1)*sizeof(char));

如果您想要复制它:

strcpy(tempSides, sides);

9
当你说 NULL 时,其实是指 '\0'。'\0' 是 nul(空字符),不是 NULL。 - George Phillips
2
@caf:没错,但是省略它会使得在必要时将代码适应wchar_t或TCHAR变得更加困难——如果没有乘法运算,就有忘记使用的风险。 - sharptooth
4
еҰӮжһңжӮЁжӢ…еҝғд»ҘеҗҺдјҡж”№з”Ёwchar_tпјҢйӮЈд№Ҳд№ҳд»Ҙsizeof *tempSidesжҳҜжңҖеҘҪзҡ„йҖүжӢ©гҖӮ - jamesdlin
3
严格来说,您的意思是“空字符”。 nul是空字符的ASCII名称;术语“nul”在C标准中没有出现过。 - dreamlax
3
他的意思是要检查malloc函数的返回值。 - jweyrich
显示剩余4条评论

10

请注意:

  1. 字符串是以零结尾的 (\0),而strlen()不计算它;
  2. 根据定义,sizeof(char)为1个字节,因此不需要;
  3. 如果您使用C(而非C++)编译器,则无需将其强制转换为char *

因此代码应该是:

char *tempSides = malloc(strlen(inSides) + 1);

如果你想要复制inSides的内容,你可以使用strdup来实现,例如:

char *tempSides = strdup(inSides);
if (tempSides != NULL) {
    // do whatever you want...
    free(tempSides);
}

2
正如指出的那样,您忘记为终止NUL字符分配空间。但我也想指出其他两个可以使您的代码更简洁的东西。
按定义,sizeof(char)始终为1,因此您可以将分配行缩短为:
tempSides = (char*)malloc(strlen(inSides) + 1);

另外一件事是,这看起来像是你要复制字符串。有一个内置函数可以为你完成这个操作:

tempSides = strdup(inSides);

这个函数负责获取长度,分配正确数量的字节并复制数据。


1

不,实际上并不是这样的。正如其他人已经指出的那样,您需要为NUL终止符分配空间。

另外,通常情况下您不应该强制转换来自malloc的返回值。这可能会掩盖您忘记#include正确头文件的错误。乘以sizeof(char)也是无意义的,因为标准(包括C和C++)将sizeof(char)定义为始终为1。

最后,每次调用malloc都应该包括对结果的测试。我建议将整个过程封装成一个函数:

char *dupe_string(char const *string) { 
    char *temp;
    if (NULL!=(temp=malloc(strlen(string)+1)))
        strcpy(temp, string);
    return temp;
}

1

这里有一个问题。tempSides将指向一个未初始化的大小为1的内存块。如果你想要将sides字符串复制到tempSides中,那么你需要分配一个比原来多一个字节的空间,以容纳字符串的零终止符。strlen()返回的值不包括字符串末尾的零终止符。


0
将元素计数乘以sizeof(char)是个人偏好的问题,因为sizeof(char)始终为1。但是,如果您出于一致性考虑这样做,最好使用接收者指针类型来确定元素大小,而不是显式指定类型。并且不要强制转换malloc的结果。
tempSides = malloc(strlen(inSides) * sizeof *tempSides);

当使用以零结尾的字符串时,当然要记得为终止零字符分配额外的空间。在这种情况下,无法确定您是否打算将tempSides设置为以零结尾的字符串,因此我无法确定您是否需要它。

不可能吧?他最好在调用 strlen 时使用零结尾字符串... 如果他使用自己的 strlen,那么我真的不想成为他之后的维护程序员。 ;) - Secure
1
@Secure:这只意味着“inSides”是以零结尾的。代码中没有任何迹象表明“tempSides”也应该以零结尾。 - AnT stands with Russia

0

tempSides分配动态内存的正确方法如下所示:

char* sides ="5";
char* tempSides;
tempSides = (char*)malloc((strlen(sides) + 1) * sizeof(char));

char* 存储字符串数据,类似于 char[]。字符串以 null (\0) 结尾。因此需要额外分配一个字节来存储 null 字符。

动态分配的内存块在使用完后必须使用 free() 进行释放。如果不释放,则可能会发生内存泄漏。

free(tempSides);

一旦释放了内存,必须将NULL分配给它,以防止它成为悬空指针。
tempSides = NULL;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接