【问题标题】:Flexible array of pointers to char in a struct结构中指向 char 的灵活指针数组
【发布时间】:2010-09-15 07:37:29
【问题描述】:

我正在尝试使用以下结构实现环形缓冲区

/*head, tail are indexes of the head and tail of ring buffer
 *count is the number of elements; size is the max size of buffer
 *rbArray is an array to pointer of char used to store strings    
 */
struct rb{
  int head;
  int tail;
  int count;
  int size;
  char *rbArray[];
};

然后我使用下面的函数来创建一个字符串缓冲区:

 struct rb *create(int n){
     /*allocate memory for struct*/
     struct rb *newRb = (struct rb*)malloc(sizeof(struct rb)+ n*sizeof(char *));
     assert(newRb);

     int i;
     for(i=0;i<n;i++)
        newRb->rbArray[i] = NULL;

     /*put head and tail at the beginning of array
     initialize count, set max number of elements*/
     newRb->head = 0;
     newRb->tail = 0;
     newRb->count = 0;
     newRb->size = n;

     return newRb;
   }

我在 main 中调用这个函数:

 struct rb *newRB = (struct rb*)create(100);

但是,我在为 struct 分配内存的步骤中遇到了问题。在调试模式下,我可以看到 head、tail、count 的值被分配了非常奇怪的大数字,但不是 0。在第一步之后程序挂起,没有抛出任何异常。

有人可以帮我解释一下这个问题吗?我该如何解决?

【问题讨论】:

  • 您的代码看起来不错(并且在我的计算机上运行良好)。我只是删除演员表并将 sizeof 应用于对象而不是类型。
  • "exception" ... 嗯:你是在编译你的代码为C(不是C++)吗?
  • 您的代码(有一些不相关的更改)在 ideone 的编译器上运行正常(ideone.com/1QLey
  • stackoverflow.com/questions/3711233/… - 虽然不是重复的,但绝对值得一看。
  • 代码看起来不错,但类型转换看起来有点可疑。 C 代码中不应该需要它们。特别是,如果编译器抱怨您的 struct rb *newRB = create(100); 调用中的类型,那么您还有其他一些被类型转换隐藏的问题。

标签: c arrays struct malloc member


【解决方案1】:

我很难阅读您的代码,但从我收集到的信息来看,您可能想要执行以下操作:

struct rb *create(int n)
{
    struct rb newRb = calloc(1, sizeof(struct rb));
    newRb->rbArray = calloc(n, sizeof(char*));

    newRb->count = n;

    return newRb;
}

calloc 将确保分配空间的内容设置为零。此外,在您第一次调用 malloc 时仅分配一个额外的 n*sizeof(char*) 似乎很可疑。

【讨论】:

  • 正确。您不能假设编译器如何对齐结构中的数据。
  • 这就是“struct hack”(C99 中的 flexibla 数组成员,chepukha 正在使用),Jim。看起来不错。
  • +1。但是为什么calloc(1,sizeof(...)) 而不仅仅是malloc(sizeof(...)) 呢?
  • 感谢您的快速回复。我试过你的代码,但在这一行有问题: newRb->rbArray = (char )calloc(n, sizeof(char));灵活数组成员的使用无效
  • 在 C99 之前,您仍然可以进行灵活的数组 hack,但是您需要将最终的数组结构元素声明为大小 1,而不是忽略它。您还必须更改 malloc 中的大小计算,以说明第一个数组元素包含在 sizeof(struct ...) 部分中。
【解决方案2】:

以下应该是执行相同操作的更短方法:

struct rb *create(int n)
{
    struct rb * newRb = calloc(sizeof(struct rb) + n*sizeof(char*), 1);
    newRb->size = n;    
    return newRb;
}

这会将所有分配的空间设置为0,然后正确设置size 字段。

【讨论】:

  • calloc(nmembers, size) -- “4200 个大小为 1 字节的成员”与“1 个大小为 4200 字节的成员”略有不同。
  • @pmg:它们是一样的。单独使用nmemberssize 的唯一原因是如果您想依靠calloc 为您的乘法进行溢出检查。
【解决方案3】:

非常感谢你们的帮助。我使它与 char** 一起工作,它绝对比灵活地工作数组成员容易得多。

但是,我想知道,当你有 字符**数组; 你可以使用array[i],它会给你一个指向char的指针。为什么如果我们有 字符*数组; 我们不能使用 array[i] 来获取字符吗?

希望我在这里足够清楚。

谢谢

【讨论】:

  • 但是最好的答案是什么?现在我不知道 char** 解决方案是什么样的。它比 calloc(n, sizeof(char*)) 解决方案更好、更差还是一样好?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-05
  • 2021-01-26
  • 2017-06-03
  • 2020-06-14
  • 1970-01-01
  • 2016-01-27
相关资源
最近更新 更多