【发布时间】:2020-03-14 08:53:02
【问题描述】:
我正在尝试从具有函数的结构中分配两个多维数组。分配第一个工作完美,但第二个失败,即使两个数组的代码完全相同。
我以为是因为我没有足够的内存,但我有 16GB 的 RAM,这甚至不需要一千字节。
如果它可以帮助我使用 CLion 和 C98。我还尝试在没有 CLion 的情况下启动导出的程序,以防它来自它。
main.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->都是与您分配的基地址的偏移量,那里最多有8 个字节。很快你就会触摸到你不拥有的内存,在这种情况下,它似乎位于calcReturn->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