C语言 如何正确分配内存并返回二维数组

njthzxwz  于 2023-02-21  发布在  其他
关注(0)|答案(2)|浏览(127)

我收到运行时错误:类型'int *'的空指针。这是我的代码:

int min (int a, int b){
    return a < b ? a : b;
}
int max (int a, int b){
    return a > b ? a : b;
}

int** intervalIntersection(
        int** firstList, int firstListSize, int* firstListColSize,
        int** secondList, int secondListSize, int* secondListColSize,
        int* returnSize, int** returnColumnSizes){
    int i = 0, j = 0;
    int a = 0;
    int **res;
    while (i < firstListSize && j < secondListSize) {
        int l = max(firstList[i][0], secondList[j][0]);
        int r = min(firstList[i][1], secondList[j][1]);
 
        if (l <= r){
            res[a][0] = l; - *I suspect error in this line*
            res[a][1] = r; - *and this also*
            a++;
        }
 
        if (firstList[i][1] < secondList[j][1])
            i++;
        else
            j++;
    }
    res = malloc(sizeof(int) * (a * 2));
    *returnSize = a;
    **returnColumnSizes = 2;
    return res;
}
runtime error: load of null pointer of type 'int *'

我需要返回这两个区间列表的交集作为一个2D数组。而且,我想我错误地malloc我的新的2D数组,所以在那之后我得到了这个错误。我将不胜感激,如果有人可以改变代码,使找到交集后,两个点添加到2D数组。
在修复@macjayz之后,我得到了堆缓冲区溢出错误

==32==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000258 at pc 0x564ab16e9fdc bp 0x7fff1adb4900 sp 0x7fff1adb48f0
READ of size 4 at 0x602000000258 thread T0
    #2 0x7f1568a4d0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
0x602000000258 is located 0 bytes to the right of 8-byte region [0x602000000250,0x602000000258)
allocated by thread T0 here:
    #0 0x7f1569692bc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #3 0x7f1568a4d0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
Shadow bytes around the buggy address:
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff8000: fa fa 00 00 fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x0c047fff8010: fa fa 00 fa fa fa 00 00 fa fa 00 fa fa fa 00 fa
  0x0c047fff8020: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x0c047fff8030: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
=>0x0c047fff8040: fa fa 00 fa fa fa 00 fa fa fa 00[fa]fa fa fd fa
  0x0c047fff8050: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c047fff8060: fa fa fd fa fa fa fd fa fa fa 00 00 fa fa fa fa
  0x0c047fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==32==ABORTING

示例:第一个列表=[[0,2],[5,10],[13,23],[24,25]]
第二个列表=[[1,5],[8,12],[1,5,24],[25,26]]
产出:[[1,2]、[5,5]、[8,10]、[15,23]、[24,24]、[25,25]]

nimxete2

nimxete21#

您正在 for 循环之后为res分配空间。当程序进入 for 循环时,res的内存尚未分配。
把分配放在循环之后的原因可能是你不知道循环之前a的确切值。如果内存消耗不是优先考虑的,你可以预先分配大量内存,然后在函数返回之前释放多余的内存。如果程序要在内存敏感的环境中运行,你可以实现一个类似于C++的vector的数据结构。即,分配一小块存储器,并且当空闲槽变少时扩展阵列。

4uqofj5v

4uqofj5v2#

提供的代码中的问题是,在尝试访问"res“之前,未正确分配内存。因此,在尝试访问”res[a][0]“和”res[a][1]“时,程序正在访问未初始化的内存,并导致运行时错误。
要为2D数组正确分配内存并避免运行时错误,需要执行以下步骤:
为指向int的指针数组分配内存为2D数组的每一行分配内存将指针数组中的每个指针分配给2D数组的相应行以下是正确分配和使用2D数组的代码的更新版本:

int min(int a, int b){
    return a < b ? a : b;
}

int max(int a, int b){
    return a > b ? a : b;
}

int** intervalIntersection(int** firstList, int firstListSize, int* firstListColSize, int** secondList, int secondListSize, int* secondListColSize, int* returnSize, int** returnColumnSizes) {
    int i = 0, j = 0, k = 0;
    int **res;
    res = malloc(sizeof(int*) * (firstListSize + secondListSize)); // allocate memory for pointers to each row of the 2D array
    for (k = 0; k < firstListSize + secondListSize; k++) {
        res[k] = malloc(sizeof(int) * 2); // allocate memory for each row of the 2D array
    }
    k = 0;
    while (i < firstListSize && j < secondListSize) {
        int l = max(firstList[i][0], secondList[j][0]);
        int r = min(firstList[i][1], secondList[j][1]);
        if (l <= r) {
            res[k][0] = l;
            res[k][1] = r;
            k++;
        }
        if (firstList[i][1] < secondList[j][1]) {
            i++;
        } else {
            j++;
        }
    }
    *returnSize = k; // set the size of the return array
    *returnColumnSizes = malloc(sizeof(int) * 2);
    (*returnColumnSizes)[0] = 2; // set the number of columns in each row of the return array
    return res;
}

在此更新代码中,我们:
为int* 数组分配内存,大小为firstListSize + secondListSize,用于保存指向2D数组每一行的指针。为2D数组每一行分配内存,大小为2。将res[k]处的指针分配给我们刚刚使用malloc分配的行的地址(sizeof(int)* 2).返回res二维数组,并将returnSize设置为a(数组中的行数),将returnColumnSizes设置为一个新的一维数组,该数组包含一个元素2,表示每行包含两列。

相关问题