c语言 - uint8_t数组返回导致使用所有方案时出错(**、* 和,无)


int8_t** FileToColorMap(char* colorfile, int* colorcount)
{
FILE* fp = fopen (colorfile, "r");
if (fp==NULL) 
{ 
printf("no such file."); 
return 0; 
} 
int r,g,b;
fscanf(fp, "%d", colorcount);
uint8_t* output;
output = (uint8_t *)malloc(*colorcount * sizeof(uint8_t));
for (int i = 0; i < *colorcount;i++) {
if( fscanf(fp, "%d %d %d", &r, &g, &b) != EOF ) {
// int* arr= (int *)malloc(3 * sizeof(int));
// arr[0] = r;
// arr[1] = g;
// arr[2] = b;
int arr[3] = {r,g,b};
output[i] = *arr;
} else
{
freeMap(i+1, &output);
return NULL;
}

}
fclose(fp);
return *output;
}

这会导致seg错误,或者错误1或其他什么,即使当我尝试返回输出,**输出,&输出。

看起来你的帖子大部分都是代码;请添加更多详细信息。

有很多问题:

  1. 类型和分配错误
uint8_t* output;
output = (uint8_t *)malloc(*colorcount * sizeof(uint8_t));

您需要在此处声明指针到指针,并为非uint8_t 的指针分配空间

两个数组的类型都不正确。arr是自动变量,在函数范围外取消引用它是UB

  • 许多其他问题
int8_t** FileToColorMap(char* colorfile, int* colorcount)
{
FILE* fp = fopen (colorfile, "r");
if (fp==NULL) 
{ 
printf("no such file."); 
return 0; 
} 
int8_t r,g,b;
if(fscanf(fp, "%d", colorcount) != 1)
{
/* fscanf failed - do something */
}
int8_t **output = malloc(*colorcount * sizeof(*output));
for (int i = 0; i < *colorcount;i++) {
if( fscanf(fp, "%hhx %hhx %hhx", &r, &g, &b) == 3) {
uint8_t *arr = malloc(3 * sizeof(*arr));
arr[0] = r;
arr[1] = g;
arr[2] = b;
output[i] = arr;
} else
{
freeMap(i+1, &output);
return NULL;
}

}
fclose(fp);
return output;
}

如果malloc,请始终检查结果。为了清楚起见,我没有

总的来说,代码是不必要的复杂。我建议使用结构,因为在这种情况下,最内部的维度总是3项宽。

假设color_count由调用者分配并返回读取的项目数,则:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct
{
uint8_t r;
uint8_t g;
uint8_t b;
} rgb_t;
rgb_t* FileToColorMap (const char* color_file, int* color_count)
{
FILE* fp = fopen (color_file, "r");
if (fp==NULL) 
{ 
*color_count = 0;
return NULL;
} 

int count;
if(fscanf(fp, "%d", &count) != 1)
{
fclose(fp);
*color_count = 0;
return NULL;
}

rgb_t* result = malloc ( sizeof(rgb_t[count]) );
if(result == NULL)
{
fclose(fp);
*color_count = 0;
return NULL;
}

for (int i = 0; i<count; i++) 
{
int r,g,b;
if( fscanf(fp, "%d %d %d", &r, &g, &b) != 3 )
{
free(result);
fclose(fp);
*color_count = 0;
return NULL;
}

result[i].r = r;
result[i].b = b;
result[i].g = g;
}
fclose(fp);
*color_count = count;
return result;
}

注:

  • 添加到文件名参数的常量正确性
  • 正确清理动态内存和文件处理错误
  • 使用临时内部变量count,直到您知道一切顺利为止。在函数末尾写入调用方的变量
  • 检查fscanf的结果是否符合预期的项目数,而不仅仅是它不是EOF

高级:

要进一步清理代码,需要查看错误处理和资源清理。上面代码中的错误处理有很多重复,这并不理想-清理应该集中在一个位置,否则很容易发生资源泄漏,特别是在以后的维护过程中

有三种方法可以做到这一点:清理宏;关于错误goto";模式或包装器函数。我更喜欢后者,因为它最不乱。这是通过将资源的所有权分解为外部函数来完成的,该函数是调用者所知道的。然后将实际的算法放入内部static函数中。

这里有一个例子,使用集中清理/错误处理:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct
{
uint8_t r;
uint8_t g;
uint8_t b;
} rgb_t;
static bool FileReadColorMap (FILE* fp, rgb_t** result, int* color_count)
{
int count;
fscanf(fp, "%d", &count);

*result = malloc ( sizeof(rgb_t[count]) );
if(*result == NULL)
{
return false;
}

for (int i = 0; i < count; i++) 
{
int r,g,b;
if( fscanf(fp, "%d %d %d", &r, &g, &b) != 3 )
{
return false;
}

(*result)[i].r = r;
(*result)[i].b = b;
(*result)[i].g = g;
}
*color_count = count;
return true;
}
rgb_t* FileToColorMap (const char* color_file, int* color_count)
{
rgb_t* result = NULL;
FILE*  fp     = NULL;

fp = fopen (color_file, "r");
if(fp == NULL)
{
*color_count = 0;
return NULL;
}

if(!FileReadColorMap(fp, &result, color_count))
{
*color_count = 0;
free(result);  // it is safe to do free(NULL)
result = NULL; // return NULL
}

fclose(fp); // always called
return result;
}

相关内容

最新更新