简体   繁体   English

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

[英]Dynamically allocating 2d array in c error

My problem is prettty simple, I wanna allocate memory for a 2d array in c, fill it with -1, then free it and exit the program. 我的问题很简单,我想为c中的2d数组分配内存,用-1填充它,然后释放它并退出程序。 My code keeps crashing and I dont know what I am doing wrong... This is what I got: 我的代码不断崩溃,我不知道自己在做什么错...这就是我得到的:

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

So what happens is that I wanna allocate an array that has 1 extra line and 1 extra column than the 2 strings if you put them vertically compared to each other. 所以发生的事情是,我想分配一个数组,如果您将它们垂直比较,则它们比2个字符串多1行和1列。

And this is what I expected( the things in bracets are obviously not part of the table, I put the there for comparison): 这就是我所期望的(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  

The problem is that the code crashes when it fills the table, and it always crashes for i=9 and j=3, for those specific strings. 问题在于,代码填充表时会崩溃,并且对于那些特定的字符串,对于i = 9和j = 3,它始终会崩溃。 The weird part is that if you swap the 2 strings(put "abc" in str1) then the code passes the filling stage, and crashes when it tries to free the array. 怪异的部分是,如果交换2个字符串(在str1中放入“ abc”),则代码将通过填充阶段,并在尝试释放数组时崩溃。

Sorry for any grammar mistakes or stackoverflow mistakes, I am kinda new here :P 抱歉任何语法错误或stackoverflow错误,我在这里有点新:P

Any idea is welcome :) thx in advance 欢迎任何想法:)提前

As a number of people have pointed out, you're allocating H_table with room for len1 + 1 integers but it is actually supposed to be an array of len1 + 1 pointers (to integers). 正如一些人所指出的那样,你分配H_table与空间len1 + 1 的整数 ,但它实际上应该是一个数组len1 + 1 的指针 (为整数)。 Since pointers are bigger than integers (on your system, anyway), you end up with undefined behaviour from a buffer overrun. 由于指针大于整数(无论如何,在系统上),所以最终会因缓冲区溢出而导致未定义的行为。

Here's a hint. 这是一个提示。 Avoid this problem, and a variety of other similar issues, by always using the following model for malloc : 通过始终对malloc使用以下模型,可以避免此问题以及其他各种类似问题:

some_variable = malloc(n * sizeof *some_variable);

For example: 例如:

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

That is, let the compiler figure out the right type for the variable (or lvalue). 也就是说,让编译器找出变量(或左值)的正确类型。 The compiler is less prone to typos than you are, and not writing the type explicitly will make it a lot easier for you to later decide that H_table should have been long or short or unsigned . 编译器不像您那样容易输入错误,并且不显式地编写该类型将使您以后确定H_table应该为longshortunsigned容易H_table

For the same reason, don't explicitly cast the return value of malloc . 出于相同的原因,请勿显式转换malloc的返回值。 C automatically casts void* to the destination type, and does not provide an error if you manually cast to the wrong type. C会自动将void*强制转换为目标类型,并且如果您手动将其强制转换为错误的类型,则不会提供错误。 So just let the compiler do it; 因此,只需让编译器执行此操作即可; it's less typing, safer, and more future-proof. 它减少了打字,更安全,并且更适合未来。

Note that if you use an expression with sizeof , the compiler does not evaluate the expression [Note 1]. 请注意,如果您使用带sizeof的表达式,则编译器不会对表达式求值[注1]。 It just figures out the type and substitutes that for the expression. 它只是弄清楚类型并将其替换为表达式。 So don't worry about extra evaluation: there isn't any. 因此,不必担心额外的评估:没有任何评估。 That's also why it's ok to use this model with declarations, even though some_variable doesn't yet have a value when the malloc is executed. 这就是为什么可以在声明中使用此模型的原因,即使在执行mallocsome_variable尚无值。


Notes: 笔记:

  1. There is one circumstance in which the compiler might evaluate ex in sizeof ex : if ex is a variable-length array. 有一种情况,其中,编译器可能评估exsizeof ex :如果ex是一个可变长度的数组。 However, in this case ex is always a pointer, so that case cannot apply. 但是,在这种情况下, ex始终是指针,因此该情况​​不适用。

As @xing mentioned in his comment, H_table is a pointer to pointer to integer. 正如@xing在他的评论中提到的, H_table是一个指向整数的指针。 so you need to change the int to int* in the first malloc . 因此,您需要在第一个malloc中将int更改为int* here: 这里:

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

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

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