在C错误中动态分配2D数组

时间:2019-03-06 18:37:23

标签: c arrays pointers malloc

我的问题很简单,我想为c中的2d数组分配内存,用-1填充它,然后释放它并退出程序。我的代码不断崩溃,我不知道自己在做什么错... 这就是我得到的:

int main(){

    int i,j;
    char str1[]="xxxabxcxxxaabbcc";
    char str2[]="abc";
    int len1=strlen(str1);
    int len2=strlen(str2);

    printf("%d %d",len1,len2);

    //allocate 2d_array

    int **H_table = (int**)malloc((len1+1)*sizeof(int));
    for (i=0; i<len1+1; i++){
        H_table[i] = (int*)malloc((len2+1)*sizeof(int));
    }

    //fill and print 2d array

    for(i=0;i<len1+1;i++){
        for(j=0;j<len2+1;j++){
            printf("i:%d j:%d",i,j);
            H_table[i][j]=-1;
            printf(" value:%d\n",H_table[i][j]);
        }
    }

    // free 2d array

    for(i=0;i<len1;i++){
        free(H_table[i]);
    }
    free(H_table);
    return 0;
}

所以发生的事情是,我想分配一个数组,如果您将它们垂直比较,则它们比2个字符串多1行和1列。

这就是我所期望的(bracets中的内容显然不是表的一部分,我将其放在此处进行比较):

   (x x x a b x c x x x a a b b c c)  
  1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
a)1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
b)1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
c)1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  

问题在于,代码填充表时会崩溃,并且对于那些特定的字符串,对于i = 9和j = 3,它总是崩溃。奇怪的是,如果交换2个字符串(在str1中输入“ abc”),则代码将通过填充阶段,并在尝试释放数组时崩溃。

很抱歉出现任何语法错误或stackoverflow错误,我在这里很新:P

欢迎提出任何想法:)提前

2 个答案:

答案 0 :(得分:1)

许多人指出,您正在为H_table分配给len1 + 1 integers 的空间,但实际上应该是{{1 }} 指针(整数)。由于指针大于整数(无论如何在系统上),所以最终会因缓冲区溢出而导致未定义的行为。

这是一个提示。通过始终对len1 + 1使用以下模型,可以避免出现此问题以及其他各种类似问题:

malloc

例如:

some_variable = malloc(n * sizeof *some_variable);

也就是说,让编译器找出变量(或左值)的正确类型。编译器不像您那样容易出现错字,并且不显式地编写类型将使您以后决定int** H_table = malloc((len1 + 1) * sizeof *H_table); for (int i = 0; i <= len1; ++i) H_table[i] = malloc((len2 + 1) * sizeof *H_table[i]); 应该是H_tablelong或{ {1}}。

出于相同的原因,请不要显式转换short的返回值。 C自动将unsigned强制转换为目标类型,并且如果您手动转换为错误的类型,则不会提供错误。因此,只需让编译器执行此操作即可;打字更简单,更安全,更能适应未来。

请注意,如果您将表达式与malloc一起使用,则编译器不会对表达式进行求值[注1]。它只是弄清楚类型并将其替换为表达式。因此,不必担心额外的评估:没有任何评估。这就是为什么可以在声明中使用此模型的原因,即使在执行void*sizeof还没有值。


注意:

  1. 在一种情况下,编译器可能会评估some_variable中的malloc:如果ex是一个可变长度数组。但是,在这种情况下,sizeof ex始终是指针,因此这种情况不适用。

答案 1 :(得分:0)

正如@xing在他的评论中提到的,H_table是指向整数的指针。因此您需要在第一个int中将int*更改为malloc。 在这里:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){

    int i,j;
    char str1[]="xxxabxcxxxaabbcc";
    char str2[]="abc";
    int len1=strlen(str1);
    int len2=strlen(str2);

    printf("%d %d",len1,len2);

    //allocate 2d_array

    int **H_table = (int**)malloc((len1+1)*sizeof(int*));
    for (i=0; i<len1+1; i++){
        H_table[i] = (int*)malloc((len2+1)*sizeof(int));
    }

    //fill and print 2d array

    for(i=0;i<len1+1;i++){
        for(j=0;j<len2+1;j++){
            printf("i:%d j:%d",i,j);
            H_table[i][j]=-1;
            printf(" value:%d\n",H_table[i][j]);
        }
    }

    // free 2d array

    for(i=0;i<len1;i++){
        free(H_table[i]);
    }
    free(H_table);
    return 0;
}