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,b};
            output[i] = *arr;
        } else
        {
            freeMap(i+1,&output);
            return NULL;
        }
        
    }
    fclose(fp);
    return *output;
}

即使我尝试返回输出,**输出输出,这也会导致段错误错误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,&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,b;
    if( fscanf(fp,"%d %d %d",&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。

高级:

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

有三种方法可以执行此操作:清理宏,“出错时跳转”模式或包装函数。我更喜欢后者,因为它最不混乱。通过将资源的所有权划分给外部函数(调用者知道的一个外部函数)来完成。然后,将实际算法放入内部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,&count);
  
  *result = malloc ( sizeof(rgb_t[count]) );
  if(*result == NULL)
  {
    return false;
  }
  
  for (int i = 0; i < count; i++) 
  {
    int r,&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;
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...