【问题标题】:Trying to create multiples small multi-dimensional arrays with malloc尝试使用 malloc 创建多个小型多维数组
【发布时间】:2020-03-14 08:53:02
【问题描述】:

我正在尝试从具有函数的结构中分配两个多维数组。分配第一个工作完美,但第二个失败,即使两个数组的代码完全相同

我以为是因为我没有足够的内存,但我有 16GB 的 RAM,这甚至不需要一千字节。

如果它可以帮助我使用 CLion 和 C98。我还尝试在没有 CLion 的情况下启动导出的程序,以防它来自它。

ma​​in.c

#include <stdio.h>
#include <stdlib.h>

#include <math.h>
#include <string.h>

#include "include/calc.h"

int main(int argc, char **argv)
{
    calc calcObject = InitCalcObject();
}

calc.h

typedef struct CalculationObjectElement {
    int ** braketArray; // <--- First array, correct allocation
    int braketCount;
    int braketHighestPriority;

    int ** squareBraketArray; // <--- Second array, fails
    int squareBraketCount;
} CalculationObjectElement, *calc;

calc InitCalcObject();

calc.c

#include <stdio.h>
#include <stdlib.h>

#include <math.h>
#include <string.h>

#include "include/calc.h"

calc InitCalcObject()
{
    calc calcReturn = malloc(sizeof(calcReturn));

    if (calcReturn == NULL) {
        FailureHandler("Malloc - Calc object");
        return NULL;
    }

    int i;

    calcReturn->braketArray = malloc(sizeof(int *) * 256); // Working great
    calcReturn->squareBraketArray = malloc(sizeof(int *) * 256); // Working great

    for (i = 0; i < 256; i++) {
        calcReturn->braketArray[i] = malloc(sizeof(int) * 2); // Working like a charm

        if (calcReturn->braketArray[i] == NULL) {
            FailureHandler(strcat("Malloc - Calc object - braketArray", (char *) i));
            return NULL;
        }

        calcReturn->squareBraketArray[i] = malloc(sizeof(int) * 2); // Not working

        if (calcReturn->squareBraketArray[i] == NULL) { 
            FailureHandler(strcat("Malloc - Calc object - squareBraketArray", (char *) i));
            return NULL;
        } //There wasn't this failure handler at first, added it desperately trying to solve this
    }

    return calcReturn;
}

当然,我正在尝试调试它并得到:

Program received signal SIGSEGV, Segmentation fault.
InitCalcObject () at F:\Codage\C\Projects\Calculator\src\calc.c:33
33          calcReturn->squareBraketArray[i] = malloc(sizeof(int) * 2);

在它崩溃之前两次 (0xC0000005)。

【问题讨论】:

  • 您没有检查循环上方mallocs 的返回值。你是如何做到的,事实上,工作和失败?你在调试器中单步执行吗?使用你这里没有展示的 printf 调试?
  • 我不太了解我的typedef/comma 规则,但是这行是错误的:calc calcReturn = malloc(sizeof(calcReturn)); 你一定是在typedef 中隐藏了一个指针,所以sizeof(calcReturn)将仅分配指针的大小(4 或 8 个字节,具体取决于您的体系结构)。在这种情况下,您要分配整个结构的大小,sizeof(CalculationObjectElement)sizeof(*calcReturn)
  • 那肯定是一个的问题。您没有分配几乎足够的空间。每个calcReturn-&gt; 都是与您分配的基地址的偏移量,那里最多有8 个字节。很快你就会触摸到你不拥有的内存,在这种情况下,它似乎位于calcReturn-&gt;squareBracket。您通过访问您不拥有的内存来调用未定义的行为。如果您想在malloc 中使用sizeof 参数,它需要从您要分配的指针“上一级”,即int* myIntPtr = malloc(45 * sizeof(*myIntPtr));
  • 您还需要了解undefined behavior 的概念。当您调用 UB 时,任何事情都可能发生,包括看起来“完美运行”。但它可能无法在下一次工作,或者在你好友的机器上,或者当你更改编译器标志/优化,或者当你完全使用另一个编译器等时。你的违规最接近程序 4:geeksforgeeks.org/undefined-behavior-c-cpp

标签: c arrays multidimensional-array segmentation-fault malloc


【解决方案1】:

感谢@Yano,我终于找到了解决方案,这太荒谬了……我发布了这个答案,以便遇到同样问题的每个人都可以解决它。

正如Yano在答案下的cmets中所说,我没有为结构分配所有空间,而只是一个指向它的指针......

我不知道我是怎么犯这个错误的,也许我应该去睡觉xD

所以如果你喜欢我,一个带有指针的结构的 typedef(这意味着你的 typedef 用 *structElement 替换了 structElement)你需要确保分配的不是结构的指针,而是所有的指针和变量在结构内部,这意味着结构本身。 因此,如果您使用 sizeof() 执行 malloc(),请不要使用它的指针(Si 您所做的 typedef)。

这是一个例子:

#include <stdio.h>
#include <stdlib.h>

// Creating the struct //
typedef struct structElement { 
    int Var1;
    int ** TwoDimensionsArray;
    float Var2;
} structElement, *pointerStructElement; 
// Doing a typedef so pointerStructElement means a pointer of the structElement itself

int main(int argc, char **argv)
{
    pointerStructElement structTest; // Declaring a POINTER of the struct
    
    if (structTest = malloc(sizeof(structElement)) == NULL) {
       printf("structTest couldn't be allocated.");
       exit(1);
    }
    /* 
       Allocating memory for the size of the struct and NOT the pointer of the 
       struct, it's where I got it wrong at first
    */
    
    printf("structTest correctly allocated !!!");

    free(structTest);

    return 0;
}

我真的希望我能帮助一些人,指针很难理解,你总是会犯这样的小错误。

再次感谢矢野 :)

祝你有美好的一天, 朱尔斯。

PS:也感谢大家的帮助:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多