简体   繁体   English

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

[英]C "Process finished with exit code 133 (interrupted by signal 5: SIGTRAP)" when converting int to string

Im currently loosing hope, because I cant find my error.我目前正在失去希望,因为我找不到我的错误。 I changed so much in my code, that its terrible now... To start in the beginning, Im having a linked list:我在我的代码中改变了很多,现在它很糟糕......从头开始,我有一个链表:

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

For that Im implementing a function, that converts every existing value (so the value of every "next" list) to a concadening string in the form "[value1, value2, ...]".为此,我实现了一个 function,它将每个现有值(因此每个“下一个”列表的值)转换为“[value1,value2,...]”形式的串联字符串。 Here is the function:这是 function:

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);
}

Im calling the function with this assertion:我用这个断言调用 function:

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);
}

The weird thing is, that when Im compiling it with Clang in the console or in the IDE it fails with the error from the headline, but in the Intellij debugger it works every other time??奇怪的是,当我在控制台或 IDE 中使用 Clang 编译它时,它因标题错误而失败,但在 Intellij 调试器中它每隔一段时间就可以工作?

Im thankfully for every advice!我很感激每一个建议!

Edit: Here hte complete error in the console-compiler:编辑:这里是控制台编译器中的完整错误:

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

and here in intellij:在 intellij 中:

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

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

"Do not lose hope, nor be sad." “不要失去希望,也不要悲伤。”

The statement:该声明:

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

allocates memory for 2 bytes, including the null-terminator.为 2 个字节分配 memory,包括空终止符。

Then, the call to strcat() :然后,调用strcat()

strcat(toString, "[");

tries to concatenate a string to uninitialized memory. If we were to look at the man page:尝试将字符串连接到未初始化的 memory。如果我们查看手册页:

The strcat() function appends the src string to the dest string, overwriting the terminating null byte ('\0') at the end of dest, and then adds a terminating null byte. strcat() function 将 src 字符串附加到 dest 字符串,覆盖 dest 末尾的终止 null 字节('\0'),然后添加终止 null 字节。 The strings may not overlap, and the dest string must have enough space for the result.字符串不能重叠,并且目标字符串必须有足够的空间用于结果。 If dest is not large enough, program behavior is unpredictable;如果 dest 不够大,程序行为是不可预测的; buffer overruns are a favorite avenue for attacking secure programs缓冲区溢出是攻击安全程序最喜欢的途径

We see that strcat() must first find the null byte that terminates the string using a search that starts at the beginning of the string, but you never initialised the contents of toString , so this invokes undefined behaviour.我们看到strcat()必须首先使用从字符串开头开始的搜索找到终止字符串的 null 字节,但您从未初始化toString的内容,因此这会调用未定义的行为。

The call to strlen() then, is unlikely to succeed:那么对strlen()的调用不太可能成功:

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

If toString was properly null-terminated, this too would allocate merely 2 bytes for result , which might not (and it surely doesn't seem to) be able to represent the value of list->value .如果toString正确地以 null 终止,这也只会为result分配 2 个字节,这可能不能(而且看起来肯定不能)能够表示list->value的值。

The subsequent calls to strcat() have the same problem.strcat()的后续调用具有相同的问题。

Aside: Do not discard the result of mallloc() .旁白:不要丢弃mallloc()的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM