【问题标题】:Sorting a dynamically allocated array of variable length strings in C在C中对动态分配的可变长度字符串数组进行排序
【发布时间】:2016-03-20 18:25:03
【问题描述】:

我有一个动态分配的字符串数组,我已经做到了,最后一项总是NULL。现在,我想实现各种排序功能,从字母开始(但我不关心这里的比较功能本身)。

我已经写了这个基本的排序函数:

void string_sort(char **array)
{
    char *tmp = malloc(sizeof(char*));
    int i = 0;

    while (array[i + 1] != NULL) {

        int j = 0;

        while (array[j + 1] != NULL) {

            if (strcmp(array[j], array[j + 1]) > 0) {
                strcpy(tmp, array[j]);                    /* line 91 */
                strcpy(array[j], array[j + 1]);           /* line 92 */
                strcpy(array[j + 1], tmp);
            }
            j++;
        }
        i++;
    }
    free(tmp);
}

现在,这个功能似乎起作用了,排序是正确的。但是 valgrind 说了很多遍:

Invalid write of size 1(第 92 行)

Invalid read of size 1(在第 91 和 92 行)

我做错了什么导致记忆受到破坏?

【问题讨论】:

  • 你有一个指针数组。你可以交换它们;无需复制字符串。由于它们的长度可变,因此无论如何这是一个非常糟糕的主意。如果你 yopc 一个字符串变短怎么办?
  • 你也分配了错误的类型。指针不是数组!
  • 您不需要为您想要完成的每种类型的排序编写完整的排序例程,使用qsort,您只需要编写一个比较函数让qsort为您处理排序. (它会比你编写的任何排序程序快 10 倍)
  • 如果您要分配一个指针数组来键入,您可以单独分配每个字符串所需的内存量。 (它被称为 jaggedragged 数组)。 qsort 与锯齿状阵列同样有效。
  • @DavidC.Rankin 是的,将它用于任何真实的事情都是不明智的,我对排序算法了解一两件事。这只是为了学习,我正在尝试更多地了解更接近硬件的东西。感谢qsort 提示!

标签: c arrays sorting memory-management


【解决方案1】:

除了复制文本,这总是会导致内存错误,除非所有文本缓冲区都具有相同的长度(不是:字符串具有相同的长度),您可以简单地交换 指针:

  if (strcmp(array[j], array[j + 1]) > 0) {
    char *tmp= array[j];              /* line 91 */
    array[j]= array[j + 1];           /* line 92 */
    array[j + 1]= tmp;
  }

【讨论】:

  • 然后我只需要char *tmp; 而不是malloc。谢谢,我正在尝试从网络开发扩展到更底层的东西,所以还没有真正的内存管理线索。
  • @Roope:您的malloc 无论如何都是错误的。实际上,您现在分配了一个char *。验证您对malloc、指针和数组的概念。
  • 我同意 Olaf 的观点,尽管您不需要 malloc 与此解决方案。
  • @Olaf 是的,我现在看到它确实是完全错误的。无论如何,验证我的概念正是我在这里所做的。感谢您的帮助。
  • @Roope:但这不是教你 C 概念的地方。堆栈溢出是一个问答网站。仅仅通过询问单个问题,您将无法获得非平凡程序所需的全貌。帮自己一个忙,读一本 C 书,从基础开始(如果它们太基础,就快点前进)。
【解决方案2】:

那是因为你正在分配你的地址长度大小的内存

char *tmp = malloc(sizeof(char*));

当你有一个比那个大的字符串时会发生什么?肯定是越界读/写和UB。这就是 valgrind 的警告。


分配足够大的内存来保存所有字符串。如果该示例中的最大字符串可以是 100 个字符,则

char *tmp = malloc(100); //size of char is 1

【讨论】:

    猜你喜欢
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    • 2013-11-05
    • 2018-03-24
    • 2016-02-09
    • 2013-12-03
    相关资源
    最近更新 更多