【问题标题】:qsort segmentation faultqsort 分段错误
【发布时间】:2012-02-11 07:35:30
【问题描述】:

所以我正在开发一个程序,该函数从 stdio 读取,并继续读取 n 个字符块中的字符。

到目前为止,我已经将所有内容存储在一个称为缓冲区的字符数组中。对于下一步,我需要对每块 n 个字符进行排序。例如,如果 n =5,字符串cats/ndogs/n 应该拆分为cats/n dogs/n,然后qsort() 需要按字母顺序排列。我就是这样称呼qsort()

qsort (buffer, (line-2)*n*(sizeof(char)),n,compare);

其中(line-2)*n*sizeof(char) 给出了数组缓冲区中的项目总数;在这种情况下为 10。

这是我的比较函数:

int compare (const void * a, const void * b)
{
   return (strcmp(*(char **)a, *(char **)b));
}

但是,当我运行它时,我总是在strcmp() 中遇到段错误。任何想法为什么?


这是加载代码:

while (!feof(stdin))
{
    for (i = 0; i < n; i++)
    {
        char l = getchar();
        if (l != EOF)
        {
            if ((i == 0) && (line != 1))
            {
                success = (int *)realloc(buffer, line*n*(sizeof(char)));
            }
            buffer[(n*(line-1))+i] = l;
        }
     }
     line = line + 1;
}

【问题讨论】:

  • 加载代码(应该真的在问题中)看起来很糟糕;你需要使用realloc()的返回值:这是你的新buffer
  • 您的char l = getchar(); 是一场小灾难; getchar() 返回 int,而不是 char。如果字符是无符号的,EOF 测试将永远不会为真。如果字符已签名,您将在读取字符代码 0xFF(通常为 U+00FF、ÿ、带分音符号的拉丁小写字母 Y 或 y-umlaut,特别是在土耳其语中使用)时得到一个虚假的 EOF。将realloc() 的返回值保存在一个新变量中是。不检查内存分配失败是,然后不使用新值代替旧值是。使用realloc() 可以移动你的记忆。
  • 1) 什么是第 2 行)你的 feof() 用法是不切实际的 3) 强制转换 malloc() et.al 是不需要的 4) realloc() 一个指向 int 指针的 char 指针很神奇! 5)什么是成功? 6) sizeof(char) 根据定义为 1。 7) 什么是缓冲区? 8) Jonathan 对 char 和 EOF 的看法。
  • 您的比较函数对于通过比较指针指向的字符串对字符指针数组进行排序是正确的。您在阅读代码中创建的数据结构不是字符指针数组——不管它是什么。重新设计您的阅读代码并验证您可以安全地回显您阅读的内容。如果您有valgrind,请使用它。然后考虑整理一下。 (提示:分配一个字符指针数组;然后为每一行分配一个新字符串。)
  • 我的贡献解决了他的 original 问题,即所有固定大小的元素并排存在于缓冲区中。

标签: c strcmp qsort


【解决方案1】:

愚蠢的问题,但是您的字符串是否以空值结尾?您似乎只有一个换行符。

另外,您可能只需要“strcmp((char *)a, (char *)b)”,因为额外的 *s 对我来说似乎是多余的。

【讨论】:

  • 它们不是以空结尾的,我是否需要在每个 n 字符的末尾添加一个空终止符才能使 strcmp 工作?所以在这个例子中,我必须让我的缓冲区长度为 12 个字符
  • 我不知道你为什么要复杂化 strcmp 函数??它应该只是 strcmp((char *)a,(char *)b)
  • 好吧,要么 null 终止它们(因此对于“ABCDE”,您需要 6 个字符的空间),因为 strcmp 将在两个字符串中查找第一个 null(因此如果没有任何字符串,则会出现内存错误) 或者可能使用 strncmp,但您需要一个全局变量来指定字符串的最大长度
  • 如果你对 c 字符串做任何工作,它们被假定为空终止。如果没有,事情就会爆炸。
  • 我被 memcmp 更改为这样调用,使用大小作为第三个参数,我不再遇到分段错误。但与此同时,函数没有做任何事情,我的数组的内容也没有得到排序..
【解决方案2】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char buffer[] ="333000222555111777888666999444";

int mycmp(void *l, void*r);
int main(void)
{
/* note: sizeof buffer is 31,
** but the integer division will round down
** , ignoring the extra nul-byte */
qsort(buffer, (sizeof buffer/3), 3, mycmp);
printf ("[%s]\n", buffer);

return 0;
}

int mycmp(void *l, void *r)
{
return memcmp(l,r,3);
}

【讨论】:

  • 我被 memcmp 更改为这样调用,使用大小作为第三个参数,我不再遇到分段错误。但与此同时,函数没有做任何事情,我的数组的内容也没有得到排序..
  • 我发布的代码只是为了演示。尽管您的代码不完整,但其中存在多个错误。尝试将阅读部分和排序部分分开,分别构建和调试。
猜你喜欢
  • 2015-05-22
  • 2018-02-15
  • 2020-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-05
  • 2021-10-31
  • 2016-02-13
相关资源
最近更新 更多