首页 > 解决方案 > leetcode实践中使用c的AddressSanitizer错误

问题描述

char * convert(char * s, int numRows){
char rows[numRows][strlen(s)];
memset( rows, '\0', numRows*strlen(s)*sizeof(char) );
int curRow=0;
bool goingDown=false;
int len=0;
char *str=s;
for(char c=*str;c=*str;++str){
    len=0;
    while(rows[curRow][len]){len++;}
    
    rows[curRow][len]=c;
    if(curRow==numRows-1||curRow==0){goingDown=!goingDown;}
    if(goingDown){curRow++;}
    else{curRow--;}
}
char *zig=malloc(strlen(s)+1);
*zig='\0';
int i=0;
for(char *row;i<numRows;i++){
    row=*(rows+i);
    zig=strcat(zig,row); 
}
return zig;

}`

我正在尝试在 c 中实现解决方案。Leetcode 向我抛出了这个:==26==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7ffd37cc1741。但我不知道是什么问题。我只能猜到那行变量有问题。测试用例是 "A" 1 。
行:0x7ffd37cc1740“A\vI\037\244U”

那么我该如何修复这段代码呢?试图更多地了解 c。

现在问题解决了。我将用 strlen(s)+1 声明 2d 字符行。因此,行变量将被 nul 终止,这对于 strcat 参数有效。谢谢!

标签: c

解决方案


您的问题(或至少是其中一个问题)出在函数定义的第一行。

char rows[numRows][strlen(s)];

在堆栈上声明一个 2D 字符数组。您不应该在堆栈中声明大小取决于运行时的变量(在这种情况下,因为变量 s 和 numrows 传递给函数)。

您应该改为使用 malloc 或替代方法动态分配内存 -

char ** rows = malloc(sizeof(char *)*numrows); // allocate memory to store `num_rows` char pointers
// for each element in rows, create a pointer with num_columns of chars amount of space
for(int i = 0 ; i < num_columns ; i++){
    rows[i] = malloc(sizeof(char) * num_columns); // store pointer in rows[i]
    // memset this memory as needed
}
// now rows[x][y] will be one char

请注意,您需要比字符串中的字符数多分配一个字符,以在 C 字符数组中添加空终止符。这可能会消除缓冲区溢出错误,尽管您的程序可能包含其他缺陷。


推荐阅读