C通用数组实现

7

我正在尝试在C语言中实现一个通用的数组列表。然而,当数据类型不是int时,列表将不包含正确的数据。例如,像123.1234这样的双精度浮点数,当将其传入列表时,它将变为000.0000。只有当数据类型是int时,它才会有正确的值。我不知道代码的哪个部分出了问题,有人能给我一个提示吗?谢谢。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "genericADT.h"

struct list_type {
   void *data;
   int elementSize;
   int size;
   int capacity;
};

ListType create(int elementSize) {
   ListType listptr = malloc(sizeof(struct list_type));

   if (listptr != NULL) {
      listptr->size = 0;
      listptr->capacity = 10;
      listptr->elementSize = elementSize;
      listptr->data = malloc(10 * (listptr->elementSize));
      if (listptr->data == NULL) {
         free(listptr);
         listptr = NULL;
      }
   }
   return listptr;
}

void push(ListType listptr, void *item) {
   if (listptr->size >= listptr->capacity) {
      void *temp = realloc(listptr->data, listptr->elementSize * (listptr->capacity + 100));
      if (temp != NULL) {
         listptr->capacity += 100;
         listptr->data = temp;

         memcpy(listptr->data + (listptr->size) * (listptr->elementSize), item, sizeof(listptr->elementSize));
         listptr->size++;
      }
   } else {
      memcpy(listptr->data + (listptr->size) * (listptr->elementSize), item, sizeof(listptr->elementSize));
      listptr->size++;
   }
}

void *get(ListType listptr, int index) {
   return listptr->data + index * (listptr->elementSize);
}

int size_is(ListType listptr) {
   return listptr->size;
}

4
sizeof(listptr->elementSize)?真的吗? - n. m.
1
malloc() 返回一个指针,你为什么要将指针赋值给 listptr - babon
@n.m. 感谢您修复代码! - Ming
建议将数组元素包含一个 void* 指向实际数据。这样使用该列表的程序就可以根据应用程序的需要来解释数据。 - user3629249
1个回答

6

你的代码存在一些小问题,但它正确地处理了双精度值。

首先,如 @n.m. 所指出的那样,你真正想使用 listptr->elementSize 而不是 sizeof(listptr->elementSize)

其次,由于你想进行指针算术运算,应该将数据声明为 char * 而不是 void *

最后,作为一种基本的优化,你应该在容量测试之后才提取实际插入代码,而不是在两个分支中都复制它。

但是,在这些修复之后,该主函数可以正确地存储和提取双精度数:

int main() {
    ListType ls = create(sizeof(double));
    double f1=1.5, f2=3.6;
    push(ls, &f1);
    push(ls, &f2);
    printf("Got %f %f\n", *((double *) get(ls, 0)), *((double *) get(ls, 1)));
    return 0;
}

正如预期的那样,它会打印出来:

Got 1.500000 3.600000

谢谢您的纠正,我已经删除了sizeof()函数,现在它可以处理double类型,但是对于字符串类型(char *),它仍然无法正常打印,会出现奇怪的符号。 - Ming
注意,如果你只存储了字符串的指针,你必须确保在使用它之前该数组不会被销毁(这被称为“悬空指针”,可以在谷歌上搜索了解更多...) - Serge Ballesta
大神,您就是我的偶像!您准确指出了问题所在!我在数组列表驱动程序的某个部分中放置了free(),这就是导致问题的原因。我将其删除后,现在一切都正常了。非常感谢! - Ming

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接