C“进程结束,退出代码为133(被信号5中断:SIGTRAP)”将int转换为字符串时

nhhxz33t  于 2023-02-03  发布在  其他
关注(0)|答案(1)|浏览(200)

我现在失去了希望,因为我找不到我的错误。我改变了这么多我的代码,现在它的可怕...开始在开始,我有一个链表:

struct list {
int value;
struct list *next;
};

为此,我实现了一个函数,将每个现有值(即每个“next”列表的值)转换为“[value 1,value 2,...]"形式的连接字符串。

char* cdl_to_string(list_t *list){
int tester = 1;
char* toString =  malloc(2 * sizeof(char));
    strcat(toString, "[");
    if(list != NULL){
        while ( tester !=0){
            char *result = malloc(strlen(toString) * sizeof(char ) +1);
            sprintf(result, "%d", list->value);
            strcat(toString,result);
            if(list->next != NULL){
                strcat(toString, ", ");
            }
            else{
                tester = 0;
            }
            list = list->next;
            free(result);
        }
    }
    strcat(toString, "]");
    printf("%s",toString);
    return toString;
    free(toString);
}

我用这个Assert调用函数:

void givenListWithMultipleElements_toStringIsOk() {
    list_t* head = create_node(INT_MIN);
    list_t* second = create_node(INT_MAX);
    list_t* third = create_node(0);
    head->next = second;
    second->next = third;

    char* result = cdl_to_string(head);

    assert(strcmp("[-2147483648, 2147483647, 0]", result) == 0);
    TEST_SUCCESS("givenListWithMultipleElements_toStringIsOk");

    free(third);
    free(second);
    free(head);
}

奇怪的是,当我在控制台或IDE中用Clang编译它时,它会失败,并出现标题中的错误,但在Intellij调试器中,它每隔一次都会工作!?
我感谢每一个建议!
编辑:这里是控制台编译器中的完整错误:

[ OK ]  whenInitList_thenListIsCreated
[ OK ]  givenEmptyList_thenReturnSizeOfZero
[ OK ]  givenListWithOneElement_thenReturnSizeOfOne
[][ OK ]    givenEmptyList_toStringIsOk
zsh: trace trap  ./a.out

这里是intellij:

[ OK ]  whenInitList_thenListIsCreated
[ OK ]  givenEmptyList_thenReturnSizeOfZero
[ OK ]  givenListWithOneElement_thenReturnSizeOfOne
[][ OK ]    givenEmptyList_toStringIsOk

Process finished with exit code 133 (interrupted by signal 5: SIGTRAP)
ulydmbyx

ulydmbyx1#

"不要失去希望,也不要悲伤"

声明:

char* toString =  malloc(2 * sizeof(char));

分配2个字节的内存,包括空终止符。
然后,调用strcat()

strcat(toString, "[");

试图将一个字符串连接到未初始化的内存中。如果我们看一下手册页:
strcat()函数的作用是:将src字符串追加到dest字符串,覆盖dest末尾的终止空字节("\0"),然后添加一个终止空字节。字符串不能重叠,并且dest字符串必须有足够的空间来存放结果。如果dest不够大,程序行为将不可预测;缓冲区溢出是攻击安全程序的常用方法
我们看到strcat()必须首先使用从字符串开头开始的搜索来找到终止字符串的空字节,但是您从未初始化toString的内容,因此这调用了未定义的行为。
因此,对strlen()的调用不太可能成功:

char *result = malloc(strlen(toString) * sizeof(char ) +1);

如果toString正确地以空值终止,这也将只为result分配2个字节,这可能(而且看起来肯定)不能表示list->value的值。
strcat()的后续调用也有同样的问题。
旁白:不要丢弃mallloc()的结果。

相关问题