strcat上的段故障
我的代码有段错误,但我真的不知道原因strcat上的段故障,c,segmentation-fault,C,Segmentation Fault,我的代码有段错误,但我真的不知道原因 char *cord_tostring(cord_t R) { if (R == NULL) return NULL; char *str = malloc(sizeof(char) * 10000); if (R->left == NULL && R->right == NULL) return R->data; strcat(str, cord_tostri
char *cord_tostring(cord_t R) {
if (R == NULL)
return NULL;
char *str = malloc(sizeof(char) * 10000);
if (R->left == NULL && R->right == NULL)
return R->data;
strcat(str, cord_tostring(R->left));
strcat(str, cord_tostring(R->right));
return str;
}
在哪里
typedef struct cord_node *cord_t;
typedef struct cord_node cord;
struct cord_node {
int len;
cord *left;
cord *right;
char *data;
};
strcat
需要以NUL结尾的字符串
函数的作用是:将
s2(包括终止的NUL字符)到字符串的结尾
由s1指向s2的初始字节覆盖NUL
s1结尾的字符。如果在对象之间进行复制
如果重叠,则行为未定义
改为
char *str = malloc(10000);
str[0] = '\0';
或者更好(正如@EugeneSh在评论中指出的)使用strcpy,它不需要NUL终止符
strcpy(str,cord_tostring(R->left));
strcat(str,cord_tostring(R->right));
您的代码中存在许多问题:
- 您不检查
是否成功。在许多系统上,malloc()
可能会失败并返回malloc()
。应该测试和报告此类故障,而不是调用未定义的行为NULL
- 由
分配的块未初始化:将其作为目标调用malloc()
具有未定义的行为。您应该将其第一个字节初始化为strcat()
或使用'\0'
而不是strcpy()
strcat()
- 在递归之前,测试
和R->left
是否都是R->right
NULL
,但如果只有一个
NULL
,则将使用
NULL`源指针调用
strcat()
- 您没有释放为每个节点分配的指针,导致大量内存泄漏,最终导致内存分配失败或更糟
- 将所有
字段连接在一起,不使用任何分隔符。这可能是预期的行为,也可能不是,这取决于你的目标数据
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *cord_tostring(cord_t R) {
if (R == NULL)
return NULL;
if (R->left == NULL && R->right == NULL)
return R->data ? strdup(R->data) : NULL;
char *s1 = cord_tostring(R->left);
char *s2 = cord_tostring(R->right);
if (s1 == NULL)
return s2;
if (s2 == NULL)
return s1;
char *s = malloc(strlen(s1) + 1 + strlen(s2) + 1);
if (s == NULL) {
fprintf(stderr, "Memory allocation failure\n");
exit(1);
}
sprintf(s, "%s %s", s1, s2);
free(s1);
free(s2);
return s;
}
#包括
#包括
#包括
字符*跳线到串(跳线R){
if(R==NULL)
返回NULL;
如果(R->left==NULL&&R->right==NULL)
返回R->data?strdup(R->data):空;
char*s1=跳线(右->左);
char*s2=跳线(R->右侧);
如果(s1==NULL)
返回s2;
if(s2==NULL)
返回s1;
char*s=malloc(strlen(s1)+1+strlen(s2)+1);
如果(s==NULL){
fprintf(stderr,“内存分配失败”);
出口(1);
}
sprintf(s,“%s%s”,s1,s2);
免费(s1);
免费(s2);
返回s;
}
请注意,
cord\u to\u string()
的返回值应在使用后释放。您的树有多大?请尝试*str=0
在strcat@Zakir之前,或者使用calloc()
,这将返回一个设置为零的数组。@Zakir将分配后的所有字节都memset为0(NULL)并不总是一个好主意。不,它只是不是。@Zakir:如果您想将所有位完全初始化为零,请使用calloc()
。使用memset()。。。。并在每次递归调用后添加free
。str[0]='\0'
可以是str[0]=0
@i486:这两个语句是等效的,但第一个语句更可取,因为它传递了额外的信息NULL
和0
在许多情况下也是等效的,但是使用NULL
是对NULL指针更明确的拼写。@chqrlieNULL
可能与0不同。但是'\0'
始终是0
,并且没有额外的信息-只有额外的字符和更差的可读性。@i486:额外的字符不一定会降低可读性:运算符周围的额外空格和适当的缩进实际上提高了可读性。在这种情况下,0
还是'\0'
更具可读性,取决于品味和当地习俗。我个人喜欢后者,但你显然不同。没关系。更重要的是一致性。简化的另一种情况是sizeof(char)*10000
,根据定义,除了类型之外,它与10000
相同。@OzgurMurat:returning“
是一个问题:应该始终分配返回值,或者调用方无法确定是否释放它。最好测试NULL
。