【问题标题】:C char arrays and pointers - merge of mergesortC char 数组和指针 - 合并排序的合并
【发布时间】:2013-02-13 02:14:21
【问题描述】:

我试图通过从管道中读取字符然后将它们放入结果字符串来实现合并。我不断收到分段错误,并且无法调试问题的根源。当我删除对该函数的调用时,问题就消失了,所以我觉得这里有些地方不正确:

MAX_LENGTH 设置为 1024,我只对大约 30 个字符进行排序,所以我相信我应该有多余的空间。

int merge(char *result, int *leftpipefd, int *rightpipefd) {
char left[MAX_LENGTH/2];
char right[MAX_LENGTH/2];
int leftpos = 0;
int rightpos = 0;
int resultpos = 0;

read(leftpipefd[READ_END], left, MAX_LENGTH/2);
read(rightpipefd[READ_END], right, MAX_LENGTH/2);

int leftlen = strlen(left);
int rightlen = strlen(right);

while (leftpos < leftlen || rightpos < rightlen) {
    if (leftpos < leftlen && rightpos < rightlen) {
        if (left[leftpos] <= right[rightpos]) {
            result[resultpos] = left[leftpos];
            resultpos++;
            leftpos++;
        } else {
            result[resultpos] = right[rightpos];
            resultpos++;
            rightpos++;
        }
    } else if (leftpos <  leftlen) {
        result[resultpos] = right[rightpos];
        resultpos++;
        rightpos++;
    } else if (rightpos <  rightlen) {
        result[resultpos] = left[leftpos];
        resultpos++;
        leftpos++;
    }
}

return EXIT_SUCCESS;
}

谁能看出我做错了什么?

【问题讨论】:

  • 尝试使用调试器。对 strlen() 的调用返回什么值?你的 leftright "strings" 是空终止的吗?
  • 最好的调试方法是什么?我的标准输入和标准输出在这个过程中连接到管道,所以我不知道如何打印。
  • @Deathcalibur “使用调试器。”调试器不仅仅意味着编写打印语句,它是一个实际的程序,例如gdb
  • @djechlin 阅读后使用 gdb 确实有帮助,谢谢!

标签: c pointers merge segmentation-fault pipe


【解决方案1】:

如果您正在将 N 个字符读入长度为 N 的缓冲区,您如何期望 strlen 函数正常工作...它至少需要一个 N+1 的缓冲区,因为必须有空间用于终止 @ 987654323@ 字符。当那不存在时,谁知道接下来会发生什么......

【讨论】:

    【解决方案2】:

    几件事...

    来自http://linux.die.net/man/2/read ...

    read() 尝试将文件描述符 fd 中的 count 个字节读入缓冲区,从 buf 开始。 如果 count 为零,则 read() 返回零并且没有其他结果。如果 count 大于 SSIZE_MAX,则结果未指定。

    什么是 MAX_LEN?是否大于 SSIZE_MAX?如果是这样,您有未定义的行为。

    如果 read()s 没有输入,您将不会读取任何内容...并且您尚未初始化的缓冲区将不会更改。你应该初始化你的缓冲区。

    来自同一页面...

    出错时返回-1,并正确设置errno。

    如果读取失败,您的缓冲区仍未定义/未初始化,但您不会检测/处理这种情况。在 read()s 之后,您需要一些错误处理代码。

    此外,在同一个手册页上,没有迹象表明您的 read() 缓冲区以空值终止。正如 Floris 指出的那样,这意味着您的 strlen()s 可能会在分配的缓冲区结束后继续读取。

    while (leftpos

    此行可能有误。如果 leftpos >= leftlen 但 rightpos &&吗?

    【讨论】:

      猜你喜欢
      • 2013-01-06
      • 2012-09-04
      • 1970-01-01
      • 2012-11-19
      • 2020-11-22
      • 2014-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多