在C中对动态分配的可变长度字符串数组进行排序

时间:2016-03-20 18:25:03

标签: c arrays sorting memory-management

我有一个动态分配的字符串数组,我已经做到这一点,以便最后一项始终是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行)

我在做什么错误导致记忆破坏?

2 个答案:

答案 0 :(得分:1)

那是因为你要分配地址长度的内存

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

当你的字符串大于那个时会发生什么?肯定是出界读/写和UB。这是valgrind警告的内容。

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

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

答案 1 :(得分: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;
  }