函数找不到失败的内存分配
Function cannot find failed memory allocation
函数int load(const char *filename, int ***ptr, enum save_format_t format)
应该从二进制或文本文件(名称保存在filename
指针下)加载数据到[=14下的矩阵=] 指向矩阵的指针。文件扩展名取决于变量格式的值:0 或 1(在我展示的函数中,只有 format=0 的选项,主要用于文本文件,因为只有这个会带来麻烦)。文件中的正确数据如下所示:
10 20 30 40 50 60 70 -1
100 200 300 400 500 600 700 800 -1
对于与上面示例完全相同的数据,应按如下方式加载数据:
int A[] = {10, 20, 30, 40, 50, 60, 70, -1};
int B[] = {100, 200, 300, 400, 500, 600, 700, 800, -1};
int D[] = {A, B, C, NULL};
这意味着每一行都必须以“-1”结尾(数据必须加载到带有“-1”的矩阵)。指向最后一行之后的行的指针应等于 NULL。
如果在任何部分关闭函数分配失败,函数应该return 4.
对扩展名为“.bin”且堆限制为 return 的文件进行了测试,此错误:
Function should return 4, but it returned 0.
我使用像 **ptr
这样的符号,因为我不允许使用方括号。
谁能帮助我如何使我的函数 return 成为正确的整数。我的功能如下:
int load(const char *filename, int ***ptr, enum save_format_t format) {
if (filename == NULL || ptr == NULL || format != 0 && format != 1) {
return 1;
}
int val = 0;
int **temp = NULL;
FILE *fp, *pp;
if (format == 0) {
int i = 0, x = 0, h = 0, w = 0;
fp = fopen(filename, "r");
if (fp == NULL) {
return 2;
}
pp = fopen(filename, "r");
if (pp == NULL) {
fclose(fp);
return 2;
}
int val2 = 0;
while (1) {
if (fscanf(fp, "%d", &val2) != 1) {
if (i == 0 || val != -1) {
fclose(fp);
fclose(pp);
return 3;
}
break;
}
val = val2;
if (val == -1) {
h++;
}
i++;
}
if (i == h) {
fclose(fp);
fclose(pp);
return 3;
}
i = 0;
fseek(fp, 0, SEEK_SET);
temp = malloc(sizeof(temp) * (h + 1));
if (temp == NULL) {
fclose(fp);
fclose(pp);
return 4;
}
*(temp + h) = NULL;
for (i = 0; i < h; i++) {
val = 0, w = 0;
while (val != -1) {
if (fscanf(pp, "%d", &val) == EOF) {
break;
}
w++;
}
if (*(temp + i) != NULL) {
*(temp + i) = (int *)malloc(sizeof(int) * w);
if (*(temp + i) == NULL) {
for (int s = 0; s < i; s++) {
free(*(temp + s));
}
free(temp);
fclose(pp);
fclose(fp);
return 4;
}
} else {
fclose(fp);
fclose(pp);
free(temp);
return 0;
}
for (x = 0; x < w; x++) {
fscanf(fp, "%d", *(temp + i) + x);
}
}
fclose(fp);
fclose(pp);
}
*ptr = temp;
return 0;
}
考虑读取字符串并使用 strtol
进行解析。
当没有可用的 RAM 时,内存分配将 return NULL。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
int load ( char const *filename, int ***ptr) {
if ( filename == NULL || ptr == NULL) {
return 1;
}
char entry[100] = "";
char *end = NULL;
int **temp = NULL;
int *temprow = NULL;
long int val = 0;
int rows = 0;
int cols = 0;
int problem = 0;
int result = 0;
FILE* fp = NULL;
fp = fopen ( filename, "r");
if ( fp == NULL) {
perror ( filename);
return 2;
}
while ( 1 == ( result = fscanf ( fp, "%99s", entry))) {
if ( -1 == val || ( 0 == rows && 0 == cols)) {
if ( -1 == val) {
++rows;
}
if ( NULL == ( temp = realloc ( *ptr, sizeof **ptr * ( rows + 2)))) {
fprintf ( stderr, "problem realloc *ptr\n");
problem = 4;
break;
}
*ptr = temp;
*( ( *ptr) + rows) = NULL;
*( ( *ptr) + rows + 1) = NULL;//sentinel
cols = 0;
}
errno = 0;
val = strtol ( entry, &end, 10);
if ( entry == end) {//nothing could be parsed to int
problem = 3;
break;
}
else if ( 0 != *end) {//extra characters after int
problem = 3;
break;
}
if ( ( errno == ERANGE && ( val == LONG_MAX || val == LONG_MIN))
|| ( errno != 0 && val == 0)) {// parsing error from strtol
perror ( "input error");
problem = 3;
break;
}
if ( val > INT_MAX || val < INT_MIN) {
problem = 3;
break;
}
if ( NULL == ( temprow = realloc ( *( ( *ptr) + rows), sizeof ***ptr * ( cols + 2)))) {
fprintf ( stderr, "problem realloc *( (*ptr) + row)\n");
problem = 4;
break;
}
*( ( *ptr) + rows) = temprow;
++cols;
*( *( ( *ptr) + rows)) = cols;//save cols in index 0
*( *( ( *ptr) + rows) + cols) = val;
}
fclose(fp);
if ( 0 == result) {
problem = 3;
}
return problem;
}
int main ( void) {
char const *filename = "ints.txt";
int **array = NULL;
int row = 0;
int each = 0;
load ( filename, &array);
row = 0;
while ( array && ( *(array + row))) {
each = 0;
while ( each <= *( *(array + row))) {
printf ( "%d\n", *( *(array + row) + each));
++each;
}
++row;
}
row = 0;
while ( array && ( *(array + row))) {
free ( *(array + row));
++row;
}
free ( array);
return 0;
}
您的代码中存在多个问题:
if (i == h)
似乎不正确:如果文件包含带有 -1
终止符的单行,换句话说是空矩阵怎么办?
temp = malloc(sizeof(temp) * (h + 1));
应该是 temp = malloc(sizeof(*temp) * (h + 1));
if (*(temp + i) != NULL) {
读取由 malloc()
分配的数组中的未初始化条目。应该删除测试,您应该始终分配行。
这是修改后的版本:
int load(const char *filename, int ***ptr, enum save_format_t format) {
if (filename == NULL || ptr == NULL || format != 0 && format != 1) {
return 1;
}
int **temp = NULL;
FILE *fp, *pp;
if (format == 0) {
int i = 0, x = 0, h = 0, w = 0, val = 0;
fp = fopen(filename, "r");
if (fp == NULL) {
return 2;
}
pp = fopen(filename, "r");
if (pp == NULL) {
fclose(fp);
return 2;
}
// determine the number of rows
val = 0;
while (fscanf(fp, "%d", &val) == 1) {
if (val == -1)
h++;
}
if (val != -1) {
// empty file or file does not end with -1
fclose(fp);
fclose(pp);
return 3;
}
temp = malloc(sizeof(*temp) * (h + 1));
if (temp == NULL) {
fclose(fp);
fclose(pp);
return 4;
}
fseek(fp, 0, SEEK_SET);
for (i = 0; i < h; i++) {
w = 0;
while (fscanf(pp, "%d", &val) == 1) {
w++;
if (val == -1)
break;
}
if (w == 0 || (*(temp + i) = malloc(sizeof(int) * w)) == NULL) {
while (i-- > 0) {
free(*(temp + i));
}
free(temp);
fclose(pp);
fclose(fp);
return 4;
}
for (x = 0; x < w; x++) {
fscanf(fp, "%d", *(temp + i) + x);
}
}
*(temp + h) = NULL;
fclose(fp);
fclose(pp);
}
*ptr = temp;
return 0;
}
函数int load(const char *filename, int ***ptr, enum save_format_t format)
应该从二进制或文本文件(名称保存在filename
指针下)加载数据到[=14下的矩阵=] 指向矩阵的指针。文件扩展名取决于变量格式的值:0 或 1(在我展示的函数中,只有 format=0 的选项,主要用于文本文件,因为只有这个会带来麻烦)。文件中的正确数据如下所示:
10 20 30 40 50 60 70 -1
100 200 300 400 500 600 700 800 -1
对于与上面示例完全相同的数据,应按如下方式加载数据:
int A[] = {10, 20, 30, 40, 50, 60, 70, -1};
int B[] = {100, 200, 300, 400, 500, 600, 700, 800, -1};
int D[] = {A, B, C, NULL};
这意味着每一行都必须以“-1”结尾(数据必须加载到带有“-1”的矩阵)。指向最后一行之后的行的指针应等于 NULL。
如果在任何部分关闭函数分配失败,函数应该return 4.
对扩展名为“.bin”且堆限制为 return 的文件进行了测试,此错误:
Function should return 4, but it returned 0.
我使用像 **ptr
这样的符号,因为我不允许使用方括号。
谁能帮助我如何使我的函数 return 成为正确的整数。我的功能如下:
int load(const char *filename, int ***ptr, enum save_format_t format) {
if (filename == NULL || ptr == NULL || format != 0 && format != 1) {
return 1;
}
int val = 0;
int **temp = NULL;
FILE *fp, *pp;
if (format == 0) {
int i = 0, x = 0, h = 0, w = 0;
fp = fopen(filename, "r");
if (fp == NULL) {
return 2;
}
pp = fopen(filename, "r");
if (pp == NULL) {
fclose(fp);
return 2;
}
int val2 = 0;
while (1) {
if (fscanf(fp, "%d", &val2) != 1) {
if (i == 0 || val != -1) {
fclose(fp);
fclose(pp);
return 3;
}
break;
}
val = val2;
if (val == -1) {
h++;
}
i++;
}
if (i == h) {
fclose(fp);
fclose(pp);
return 3;
}
i = 0;
fseek(fp, 0, SEEK_SET);
temp = malloc(sizeof(temp) * (h + 1));
if (temp == NULL) {
fclose(fp);
fclose(pp);
return 4;
}
*(temp + h) = NULL;
for (i = 0; i < h; i++) {
val = 0, w = 0;
while (val != -1) {
if (fscanf(pp, "%d", &val) == EOF) {
break;
}
w++;
}
if (*(temp + i) != NULL) {
*(temp + i) = (int *)malloc(sizeof(int) * w);
if (*(temp + i) == NULL) {
for (int s = 0; s < i; s++) {
free(*(temp + s));
}
free(temp);
fclose(pp);
fclose(fp);
return 4;
}
} else {
fclose(fp);
fclose(pp);
free(temp);
return 0;
}
for (x = 0; x < w; x++) {
fscanf(fp, "%d", *(temp + i) + x);
}
}
fclose(fp);
fclose(pp);
}
*ptr = temp;
return 0;
}
考虑读取字符串并使用 strtol
进行解析。
当没有可用的 RAM 时,内存分配将 return NULL。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
int load ( char const *filename, int ***ptr) {
if ( filename == NULL || ptr == NULL) {
return 1;
}
char entry[100] = "";
char *end = NULL;
int **temp = NULL;
int *temprow = NULL;
long int val = 0;
int rows = 0;
int cols = 0;
int problem = 0;
int result = 0;
FILE* fp = NULL;
fp = fopen ( filename, "r");
if ( fp == NULL) {
perror ( filename);
return 2;
}
while ( 1 == ( result = fscanf ( fp, "%99s", entry))) {
if ( -1 == val || ( 0 == rows && 0 == cols)) {
if ( -1 == val) {
++rows;
}
if ( NULL == ( temp = realloc ( *ptr, sizeof **ptr * ( rows + 2)))) {
fprintf ( stderr, "problem realloc *ptr\n");
problem = 4;
break;
}
*ptr = temp;
*( ( *ptr) + rows) = NULL;
*( ( *ptr) + rows + 1) = NULL;//sentinel
cols = 0;
}
errno = 0;
val = strtol ( entry, &end, 10);
if ( entry == end) {//nothing could be parsed to int
problem = 3;
break;
}
else if ( 0 != *end) {//extra characters after int
problem = 3;
break;
}
if ( ( errno == ERANGE && ( val == LONG_MAX || val == LONG_MIN))
|| ( errno != 0 && val == 0)) {// parsing error from strtol
perror ( "input error");
problem = 3;
break;
}
if ( val > INT_MAX || val < INT_MIN) {
problem = 3;
break;
}
if ( NULL == ( temprow = realloc ( *( ( *ptr) + rows), sizeof ***ptr * ( cols + 2)))) {
fprintf ( stderr, "problem realloc *( (*ptr) + row)\n");
problem = 4;
break;
}
*( ( *ptr) + rows) = temprow;
++cols;
*( *( ( *ptr) + rows)) = cols;//save cols in index 0
*( *( ( *ptr) + rows) + cols) = val;
}
fclose(fp);
if ( 0 == result) {
problem = 3;
}
return problem;
}
int main ( void) {
char const *filename = "ints.txt";
int **array = NULL;
int row = 0;
int each = 0;
load ( filename, &array);
row = 0;
while ( array && ( *(array + row))) {
each = 0;
while ( each <= *( *(array + row))) {
printf ( "%d\n", *( *(array + row) + each));
++each;
}
++row;
}
row = 0;
while ( array && ( *(array + row))) {
free ( *(array + row));
++row;
}
free ( array);
return 0;
}
您的代码中存在多个问题:
if (i == h)
似乎不正确:如果文件包含带有-1
终止符的单行,换句话说是空矩阵怎么办?temp = malloc(sizeof(temp) * (h + 1));
应该是temp = malloc(sizeof(*temp) * (h + 1));
if (*(temp + i) != NULL) {
读取由malloc()
分配的数组中的未初始化条目。应该删除测试,您应该始终分配行。
这是修改后的版本:
int load(const char *filename, int ***ptr, enum save_format_t format) {
if (filename == NULL || ptr == NULL || format != 0 && format != 1) {
return 1;
}
int **temp = NULL;
FILE *fp, *pp;
if (format == 0) {
int i = 0, x = 0, h = 0, w = 0, val = 0;
fp = fopen(filename, "r");
if (fp == NULL) {
return 2;
}
pp = fopen(filename, "r");
if (pp == NULL) {
fclose(fp);
return 2;
}
// determine the number of rows
val = 0;
while (fscanf(fp, "%d", &val) == 1) {
if (val == -1)
h++;
}
if (val != -1) {
// empty file or file does not end with -1
fclose(fp);
fclose(pp);
return 3;
}
temp = malloc(sizeof(*temp) * (h + 1));
if (temp == NULL) {
fclose(fp);
fclose(pp);
return 4;
}
fseek(fp, 0, SEEK_SET);
for (i = 0; i < h; i++) {
w = 0;
while (fscanf(pp, "%d", &val) == 1) {
w++;
if (val == -1)
break;
}
if (w == 0 || (*(temp + i) = malloc(sizeof(int) * w)) == NULL) {
while (i-- > 0) {
free(*(temp + i));
}
free(temp);
fclose(pp);
fclose(fp);
return 4;
}
for (x = 0; x < w; x++) {
fscanf(fp, "%d", *(temp + i) + x);
}
}
*(temp + h) = NULL;
fclose(fp);
fclose(pp);
}
*ptr = temp;
return 0;
}