gpt4 book ai didi

c - 我的指针错误在哪里?

转载 作者:行者123 更新时间:2023-12-02 05:58:59 25 4
gpt4 key购买 nike

我已经遍历了以下代码,但找不到问题所在。函数 getsxnremem() 使用 fgets() 获取最多 len 个字符的字符串,用 null 覆盖换行符(如果有的话) -终止符,然后重新调整内存大小以适应字符串。无论如何,这就是想法。

以下代码时而有效,时而崩溃。这种情况过去发生过很多次,我通常都能找到问题所在,但这次我花了太长时间。

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

unsigned getsxnremem(char **str, unsigned len){
unsigned l, flag = 1;
free(*str);
char *buff;
if ((*str = malloc(len)) == NULL) return 0;
if(fgets(*str, len, stdin) == NULL) { free(*str); return 0; }
l = strlen(*str);
if (l && ((*str)[l-1] == '\n')) { *(str)[l-1] = '\0'; flag = 0; }
if ((buff = realloc(*str, l + flag)) == NULL){ free(*str); return 0; }
*str = buff;
return (l - 1);
}


int main(void){
char *buff = NULL;
unsigned l = getsxnremem(&buff, 256);
printf("%s\n%u chars long.", buff, l);
}

最佳答案

问题是,你收集realloc()的返回值失败了那里。

根据 C11标准,章节 §7.22.3.5

#include <stdlib.h>
void *realloc(void *ptr, size_t size);

The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. [...]

realloc()调整内存大小并返回指向新内存的指针。旧内存是free() d,考虑realloc()成功了。

所以,

  1. 你需要收集并查看realloc()的返回值并针对 NULL 进行测试以确保成功。然后,将其重新分配给 *str .

    注意:请不要使用类似 p = realloc(p, newsize); 的形式因为,那么,如果 realloc()失败,你最终也会失去实际的指针。

  2. 如果 realloc()成功了,一定不要free() 指针。打电话free()已经free() -d 内存调用 undefined behavior .

在那之后,正如 other answer 中正确提到的那样通过 dbush , 用法

 { *(str)[l-1] = '\0'; flag = 0; }

也是错误的。您所需的字符串*str 表示, 不是 str .根据 operator precedence , 数组下标运算符 ( [] ) 的优先级高于取消引用 ( * ) 运算符,所以基本上你的代码看起来像

{ * ((str)[l-1]) = '\0'; flag = 0; }

这不是你想要的。所以,为了纪念operator precedence ,你应该像这样修改它

{ (*str)[l-1] = '\0'; flag = 0; }

也就是说,您还应该检查 fgets() 的返回值在使用目标缓冲区之前确保成功。作为malloc()返回单元化内存,如果 fgets()失败,您最终会从未初始化的内存中读取数据,这将再次导致 UB。

关于c - 我的指针错误在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35344088/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com