C - 自由函数崩溃
C - free function crashes
我尝试检查地址,所有地址看起来都正常,打印正常,其他一切正常。
但是当它试图释放内存时,程序崩溃了。
代码:
#include <stdio.h>
#include <stdlib.h>
#define FIRST_DIM 2
#define SECOND_DIM 3
#define THIRD_DIM 2
#define TOTAL 12
void getNums(float* pArr);
void sortArr(float* pArr);
void printArr(float* pArr);
int main(void)
{
// Variable assignment
unsigned int i = 0, j = 0;
float*** pppArr = NULL;
// Memory assignment
pppArr = (float***)calloc(FIRST_DIM, sizeof(float**));
if (!(pppArr))
{
printf("Failed Allocating Memory..\n");
system("PAUSE");
return 1;
}
for (i = 0; i < FIRST_DIM; i++)
{
*(pppArr + i) = (float**)calloc(SECOND_DIM, sizeof(float*));
if (!(*(pppArr + i)))
{
printf("Failed Allocating Memory..\n");
system("PAUSE");
return 1;
}
}
for (i = 0; i < FIRST_DIM; i++)
{
for (j = 0; j < SECOND_DIM; j++)
{
*(*(pppArr + i) + j) = (float*)calloc(THIRD_DIM, sizeof(float));
if (!(*(*(pppArr + i) + j)))
{
printf("Failed Allocating Memory..\n");
system("PAUSE");
return 1;
}
printf("%p && %d\n", *(*(pppArr + i) + j), **(*(pppArr + i) + j));
}
}
printf("ASD");
// Getting numbers, sorting them and printing them out
getNums(**pppArr);
sortArr(**pppArr);
printArr(**pppArr);
// End of program
// Releasing memory
for (i = 0; i < FIRST_DIM; i++)
{
for (j = 0; j < SECOND_DIM; j++)
{
free(*(*(pppArr + i) + j));
}
}
for (i = 0; i < FIRST_DIM; i++)
{
printf("%p\n", *(pppArr + i));
free(*(pppArr + i));
}
free(pppArr);
system("pause");
return 0;
}
/* This function gets values for the given array from the user */
void getNums(float* pArr)
{
unsigned int i = 0;
for (i = 0; i < TOTAL; i++)
{
printf("Enter Number %d: ", i);
scanf("%f", pArr + i);
getchar();
}
}
/* This function prints out the given array */
void printArr(float* pArr)
{
unsigned int i = 0;
for (i = 0; i < TOTAL; i++)
{
printf("Number %d: %.2f\n", i, *(pArr + i));
}
}
/* This function sorts the given array from lowest to highest*/
void sortArr(float* pArr)
{
unsigned int i = 0, j = 0;
float temp = 0;
for (i = 0; i < TOTAL; i++)
{
for (j = 0; j < TOTAL - 1; j++)
{
if (*(pArr + j) > *(pArr + j + 1))
{
temp = *(pArr + j);
*(pArr + j) = *(pArr + j + 1);
*(pArr + j+ 1) = temp;
}
}
}
}
我有什么遗漏吗?
当你使用指针和动态分配时,你分配的内存很可能不是连续的,但你会为每个分配获得单独的内存区域。这意味着当您将其视为函数中的一个大的连续内存区域时,您会表现出 未定义的行为.
一个实际的数组,例如
float arr[FIRST_DIM][SECOND_DIM][THIRD_DIM];
现在将是连续的。
参见例如this old answer of mine 获取更多 "graphical" 对数组的数组与指针之间的区别的解释。
此代码的索引越界相当严重。为 pppArr
分配的内存具有三个间接级别。它不是多维数组(即不是数组的数组),而是指向指针数组的指针数组的指针。三个层次的间接性。有 6 个单独的 float
切片,每个切片有 2 个连续元素(即 THIRD_DIM
)。
当调用 getNums
、sortArr
和 printArr
时,您传递的是 **pppArr
。这等效于传递 pppArr[0][0]
,它指向 float
值的单个 2 元素序列。这些函数只能访问 THIRD_DIM
个元素,即 2。相反,它们试图访问 12 个元素(即 TOTAL
),这当然会破坏内存并导致未定义的行为。
据我所知,您似乎正试图将存储作为单个一维数组访问。如果是这样,那么修复它的最简单方法是消除 2 级间接寻址,并摆脱 FIRST_DIM
、SECOND_DIM
和 THIRD_DIM
,并只分配一个平面数组LENGTH
个元素。指针的类型为 float *
.
我尝试检查地址,所有地址看起来都正常,打印正常,其他一切正常。 但是当它试图释放内存时,程序崩溃了。 代码:
#include <stdio.h>
#include <stdlib.h>
#define FIRST_DIM 2
#define SECOND_DIM 3
#define THIRD_DIM 2
#define TOTAL 12
void getNums(float* pArr);
void sortArr(float* pArr);
void printArr(float* pArr);
int main(void)
{
// Variable assignment
unsigned int i = 0, j = 0;
float*** pppArr = NULL;
// Memory assignment
pppArr = (float***)calloc(FIRST_DIM, sizeof(float**));
if (!(pppArr))
{
printf("Failed Allocating Memory..\n");
system("PAUSE");
return 1;
}
for (i = 0; i < FIRST_DIM; i++)
{
*(pppArr + i) = (float**)calloc(SECOND_DIM, sizeof(float*));
if (!(*(pppArr + i)))
{
printf("Failed Allocating Memory..\n");
system("PAUSE");
return 1;
}
}
for (i = 0; i < FIRST_DIM; i++)
{
for (j = 0; j < SECOND_DIM; j++)
{
*(*(pppArr + i) + j) = (float*)calloc(THIRD_DIM, sizeof(float));
if (!(*(*(pppArr + i) + j)))
{
printf("Failed Allocating Memory..\n");
system("PAUSE");
return 1;
}
printf("%p && %d\n", *(*(pppArr + i) + j), **(*(pppArr + i) + j));
}
}
printf("ASD");
// Getting numbers, sorting them and printing them out
getNums(**pppArr);
sortArr(**pppArr);
printArr(**pppArr);
// End of program
// Releasing memory
for (i = 0; i < FIRST_DIM; i++)
{
for (j = 0; j < SECOND_DIM; j++)
{
free(*(*(pppArr + i) + j));
}
}
for (i = 0; i < FIRST_DIM; i++)
{
printf("%p\n", *(pppArr + i));
free(*(pppArr + i));
}
free(pppArr);
system("pause");
return 0;
}
/* This function gets values for the given array from the user */
void getNums(float* pArr)
{
unsigned int i = 0;
for (i = 0; i < TOTAL; i++)
{
printf("Enter Number %d: ", i);
scanf("%f", pArr + i);
getchar();
}
}
/* This function prints out the given array */
void printArr(float* pArr)
{
unsigned int i = 0;
for (i = 0; i < TOTAL; i++)
{
printf("Number %d: %.2f\n", i, *(pArr + i));
}
}
/* This function sorts the given array from lowest to highest*/
void sortArr(float* pArr)
{
unsigned int i = 0, j = 0;
float temp = 0;
for (i = 0; i < TOTAL; i++)
{
for (j = 0; j < TOTAL - 1; j++)
{
if (*(pArr + j) > *(pArr + j + 1))
{
temp = *(pArr + j);
*(pArr + j) = *(pArr + j + 1);
*(pArr + j+ 1) = temp;
}
}
}
}
我有什么遗漏吗?
当你使用指针和动态分配时,你分配的内存很可能不是连续的,但你会为每个分配获得单独的内存区域。这意味着当您将其视为函数中的一个大的连续内存区域时,您会表现出 未定义的行为.
一个实际的数组,例如
float arr[FIRST_DIM][SECOND_DIM][THIRD_DIM];
现在将是连续的。
参见例如this old answer of mine 获取更多 "graphical" 对数组的数组与指针之间的区别的解释。
此代码的索引越界相当严重。为 pppArr
分配的内存具有三个间接级别。它不是多维数组(即不是数组的数组),而是指向指针数组的指针数组的指针。三个层次的间接性。有 6 个单独的 float
切片,每个切片有 2 个连续元素(即 THIRD_DIM
)。
当调用 getNums
、sortArr
和 printArr
时,您传递的是 **pppArr
。这等效于传递 pppArr[0][0]
,它指向 float
值的单个 2 元素序列。这些函数只能访问 THIRD_DIM
个元素,即 2。相反,它们试图访问 12 个元素(即 TOTAL
),这当然会破坏内存并导致未定义的行为。
据我所知,您似乎正试图将存储作为单个一维数组访问。如果是这样,那么修复它的最简单方法是消除 2 级间接寻址,并摆脱 FIRST_DIM
、SECOND_DIM
和 THIRD_DIM
,并只分配一个平面数组LENGTH
个元素。指针的类型为 float *
.