C 中的数组列表不工作

发布于 2024-09-24 06:49:47 字数 2591 浏览 1 评论 0原文

我目前正在编写一个程序来在 C 中实现数组列表(或动态数组)。嗯...我想我已经完成了 70 - 80%,但是,在对几个代码进行测试时,我发现我的代码存在严重问题的机器。

简而言之,我将一组字符串( char* )插入到我的数组列表中,并尝试在几次操作后获取并显示它们。然而,这就是我得到的结果:

CHECK: 1
CHECK: 2
CHECK: ܗ¿èۗ¿
CHECK: EàEàHAÿE؉Ⱥ
CHECK: 5
CHECK: 6

不幸的是,尽管我已经检查了代码两次,但我仍然无法找出代码中的问题所在。

数组列表.h

#ifndef _ARRAYLIST_H
#define _ARRAYLIST_H

#include <stdio.h>

typedef char* value_type;

struct arraylist {
  int size;
  value_type* data;
};

extern void arraylist_initial(struct arraylist *list);
extern int arraylist_get_size(const struct arraylist list);
extern value_type* arraylist_get_data_collection(const struct arraylist list);
extern void arraylist_set_data_collection(struct arraylist *list, value_type* data);
extern void arraylist_add(struct arraylist *list, value_type value);
extern value_type arraylist_get(const struct arraylist list, int index);
extern int arraylist_indexof(const struct arraylist list, value_type value);

#endif

数组列表.c

#include "arraylist.h"

void arraylist_initial(struct arraylist *list) {
  list->size = 0;
  list->data = NULL;
}

int arraylist_get_size(const struct arraylist list) {
  return list.size;
}

value_type* arraylist_get_data_collection(const struct arraylist list) {
  return list.data;
}

void arraylist_set_data_collection(struct arraylist *list, value_type* data) {
  list->data = data;
}

void arraylist_add(struct arraylist *list, value_type value) {
  int size = arraylist_get_size(*list);
  value_type new_data[size + 1];

  int index = 0;
  for(; index != size; ++index) {
    new_data[index] = arraylist_get(*list, index);
  }
  new_data[index] = value;

  arraylist_set_data_collection(list, new_data);

  ++list->size;
}

value_type arraylist_get(const struct arraylist list, int index) {
  if(index < arraylist_get_size(list)) {
    return list.data[index];
  }
  else {
    return NULL;
  }
}

int arraylist_indexof(const struct arraylist list, value_type value) {
  int index = 0;
  for(; index != arraylist_get_size(list); ++index) {
    if(strcmp(list.data[index], value) == 0) {
      return index;
    }
  }

  return -1;
}

int main(void){
  struct arraylist list;

  arraylist_initial(&list);

  arraylist_add(&list, "1");
  arraylist_add(&list, "2");
  arraylist_add(&list, "3");
  arraylist_add(&list, "4");
  arraylist_add(&list, "5");
  arraylist_add(&list, "6");

  int index = 0;
  for(; index != 6; ++index) {
    printf("CHECK: %s\n", arraylist_get(list, index));
  }

  return 0;
}

I am currently writing a program to implement an arraylist (or dynamic array) in C. Hmm... I think I have 70 - 80% done with it, however, I found a serious problem with my code when testing them on a couple of machines.

Briefly, I inserted a group of strings( char* ) into my arraylist, and tried to get and display them after couples of operations. However, this is what I got:

CHECK: 1
CHECK: 2
CHECK: ܗ¿èۗ¿
CHECK: EàEàHAÿE؉Ⱥ
CHECK: 5
CHECK: 6

Unfortunately, I still cannot figure out where the problem is in my codes, even though I have reviewed my codes twice.

arraylist.h

#ifndef _ARRAYLIST_H
#define _ARRAYLIST_H

#include <stdio.h>

typedef char* value_type;

struct arraylist {
  int size;
  value_type* data;
};

extern void arraylist_initial(struct arraylist *list);
extern int arraylist_get_size(const struct arraylist list);
extern value_type* arraylist_get_data_collection(const struct arraylist list);
extern void arraylist_set_data_collection(struct arraylist *list, value_type* data);
extern void arraylist_add(struct arraylist *list, value_type value);
extern value_type arraylist_get(const struct arraylist list, int index);
extern int arraylist_indexof(const struct arraylist list, value_type value);

#endif

arraylist.c

#include "arraylist.h"

void arraylist_initial(struct arraylist *list) {
  list->size = 0;
  list->data = NULL;
}

int arraylist_get_size(const struct arraylist list) {
  return list.size;
}

value_type* arraylist_get_data_collection(const struct arraylist list) {
  return list.data;
}

void arraylist_set_data_collection(struct arraylist *list, value_type* data) {
  list->data = data;
}

void arraylist_add(struct arraylist *list, value_type value) {
  int size = arraylist_get_size(*list);
  value_type new_data[size + 1];

  int index = 0;
  for(; index != size; ++index) {
    new_data[index] = arraylist_get(*list, index);
  }
  new_data[index] = value;

  arraylist_set_data_collection(list, new_data);

  ++list->size;
}

value_type arraylist_get(const struct arraylist list, int index) {
  if(index < arraylist_get_size(list)) {
    return list.data[index];
  }
  else {
    return NULL;
  }
}

int arraylist_indexof(const struct arraylist list, value_type value) {
  int index = 0;
  for(; index != arraylist_get_size(list); ++index) {
    if(strcmp(list.data[index], value) == 0) {
      return index;
    }
  }

  return -1;
}

int main(void){
  struct arraylist list;

  arraylist_initial(&list);

  arraylist_add(&list, "1");
  arraylist_add(&list, "2");
  arraylist_add(&list, "3");
  arraylist_add(&list, "4");
  arraylist_add(&list, "5");
  arraylist_add(&list, "6");

  int index = 0;
  for(; index != 6; ++index) {
    printf("CHECK: %s\n", arraylist_get(list, index));
  }

  return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一直在等你来 2024-10-01 06:49:47

正如其他人所指出的,问题出在 arraylist_add() 函数中,该函数需要动态分配内存。这个问题实际上非常适合 realloc(),它将扩展动态分配的数组(意味着您不必执行复制循环):

void arraylist_add(struct arraylist *list, value_type value) {
  int size = arraylist_get_size(*list);
  value_type *new_data;

  new_data = realloc(list->data, (size + 1) * sizeof new_data[0]);

  if (new_data)
  {
      new_data[size] = value;
      arraylist_set_data_collection(list, new_data);
      ++list->size;
  }
}

这甚至适用于第一次分配,因为 <如果您向其传递 NULL,则 code>realloc() 的工作方式与 malloc() 类似。

PS:

为了提高实现效率,您不应每次将数组扩展一个条目 - 相反,应分别跟踪已分配块的数量和条目的数量。

As others have noted, the problem is in the arraylist_add() function, which needs to dynamically allocate memory. This problem is actually perfectly suited for realloc(), which will expand the dynamically allocated array (meaning you don't have to do the copying loop):

void arraylist_add(struct arraylist *list, value_type value) {
  int size = arraylist_get_size(*list);
  value_type *new_data;

  new_data = realloc(list->data, (size + 1) * sizeof new_data[0]);

  if (new_data)
  {
      new_data[size] = value;
      arraylist_set_data_collection(list, new_data);
      ++list->size;
  }
}

This will even work for the first allocation, since realloc() works like malloc() if you pass it a NULL.

PS:

To make the implementation more efficient, you shouldn't expand the array by one entry each time - instead, keep track of the number of allocated blocks separately from the number of entries.

下雨或天晴 2024-10-01 06:49:47

在 arraylist_add 方法中,您将局部变量 new_data 的地址存储到列表中。一旦控件脱离函数,该变量就会被销毁。因此,您有无效的指针,当解除引用时会调用未定义的行为。要解决此问题,您需要使用 malloc 从堆中为字符串分配内存,即您需要执行类似 value_type* new_data = (value_type*)malloc( (size + 1) * 的操作sizeof(value_type));。另请记住,您必须使用free自行释放该内存。

In the arraylist_add method you are storing the address of a local variable new_data in to the list. This variable will destroyed as soon as the control comes out of the function. Hence you have invalid pointers which when derefrenced invoke undefined behavior. To fix this problem, you need to allocate memory for the string from heap using malloc i.e. you need to do something like value_type* new_data = (value_type*)malloc( (size + 1) * sizeof(value_type));. Also remember that you have to deallocate this memory yourself using free.

雨后彩虹 2024-10-01 06:49:47

乍一看:在 arraylist_add 中,您将 new_data 声明为局部变量。当您将其传递给 arraylist_set_data_collection 时,它会传递指向该数据的指针。然而,一旦 arraylist_add 返回到 main,new_data 就超出了范围,因此不再有效。

考虑进行深度复制并使用 malloc 和 free 手动处理内存。

At first glance: in arraylist_add you declare new_data as a local variable. When you pass that to arraylist_set_data_collection, it passes the pointer to this data. However, once arraylist_add returns to main, new_data is out of scope, and is therefore no longer valid.

Consider doing a deep copy and handling the memory manually with malloc and free.

亽野灬性zι浪 2024-10-01 06:49:47

问题的根源在于:

void arraylist_add(struct arraylist *list, value_type value) {
  int size = arraylist_get_size(*list);
  value_type new_data[size + 1];
  ...
  arraylist_set_data_collection(list, new_data);
  ...
  ++list->size;
}

new_data 在堆栈上声明。调用返回后使用该内存不再安全。您需要使用malloc为数据分配空间,例如

The root of your problem is here:

void arraylist_add(struct arraylist *list, value_type value) {
  int size = arraylist_get_size(*list);
  value_type new_data[size + 1];
  ...
  arraylist_set_data_collection(list, new_data);
  ...
  ++list->size;
}

new_data is declared on the stack. It's no longer safe to use that memory after the call returns. You need to allocate space for the data with malloc, e.g.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文