c - 读取变量时出错,无法访问地址 X 的内存

标签 c

可能只是 C 新手提出的另一个愚蠢的指针问题。虽然无法弄清楚这一点。似乎我的堆栈框架以某种方式损坏了。作业看起来几乎无关紧要,但它是一个相当基本的 I/O 练习。尝试通过单次读取读取结构数组(不能使用高级 I/O 函数,例如 fread())。

#include "A2_Phase2.h"

void read_directory(Cdir directory[], int cnt) 
{
    int fd;
    char filename[] = "RandomStructDir.bin";

    fd = open(filename, O_RDONLY, S_IRWXU);
    if (fd < 0)
        perror(strcat(filename, " failed to open."));

    if (read(fd, &(directory[0].code[0]), sizeof(Cdir) * cnt) < 0) {
        perror(strcat(filename, " could not be accessed."));
    }

    close(fd);
}

int binary_search(Cdir directory[], char *key, int l, int r) {

    int mid = (int) r / 2;

    if (strncmp(key, directory[mid].code, 3) < 0)
        return binary_search(directory, key, l, mid - 1);
    else if (strncmp(key, directory[mid].code, 3) > 0)
        return binary_search(directory, key, mid + 1, r);
    else
        return mid;
}

int main(int argc, char *argv[]) 
{
    int COUNTRY_COUNT = atoi(argv[1]);
    printf("%d", COUNTRY_COUNT);

    Cdir *directory = (Cdir *) malloc(sizeof(Cdir) * COUNTRY_COUNT);
    read_directory(directory, COUNTRY_COUNT);
    binary_search(directory, "ZWE", 0, 238);
    free(directory);
}

我通过 GDB 收到此错误:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400940 in binary_search (
    directory=<error reading variable: Cannot access memory at address 0x7fffff7feff8>, 
    key=<error reading variable: Cannot access memory at address 0x7fffff7feff0>, l=<error reading variable: Cannot access memory at address 0x7fffff7fefec>, 
    r=<error reading variable: Cannot access memory at address 0x7fffff7fefe8>)
    at A2_Phase2.c:19
19  int binary_search(Cdir directory[], char *key, int l, int r) { 

谢谢!

最佳答案

int COUNTRY_COUNT = atoi(argv[1]);

读取国家的数量作为程序的参数,但稍后您在调用时硬编码假设这是 >= 238

binary_search(directory, "ZWE", 0, 238);

你能试试吗

binary_search(directory, "ZWE", 0, COUNTRY_COUNT-1);

相反?您的 binary_search 函数中也有一些错误,可以重写为

int binary_search(Cdir directory[], const char *key, int l, int r)
{
    int mid = (r + l) / 2;
    int cmp = strncmp(key, directory[mid].code, 3);
    if (l >= r) {
        if (cmp == 0)
            return l;
        return -1;
    }
    if (cmp < 0) 
        return binary_search(directory, key, l, mid - 1);
    else if (cmp > 0)
        return binary_search(directory, key, mid + 1, r);
    else
        return mid;
}

主要变化是

  • mid 的计算考虑了 l 以及 r
  • (正如 Kirilenko 所指出的)认识到可能找不到匹配项。在这种情况下返回 -1
  • 减少调用 strcmp 的次数。非常小,但它使代码对我来说更清晰,并将提高搜索性能

次要的是,有一些风格问题使您的代码难以阅读

  • 函数内大量不必要的空格
  • 对变量使用大写字母(例如 COUNTRY_COUNT)是不常见的。所有大写通常非正式地保留给使用小写或驼峰式命名的变量定义

关于c - 读取变量时出错,无法访问地址 X 的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14484682/

相关文章:

c - 在 C 中使用条件语句打印多个格式化字符串

c - 为什么当我写任何其他数字时输出总是数字 1?

c - fgets 似乎会导致写入文件

c - 我们如何在Linux 2.6 中从保护模式切换到实模式?

java - 如何从接收到的数据中正确提取信息?

c - 如何定义枚举增量步骤?

c - 使用管道将文件 i/o 传输到另一个进程

c - 想要将一些数据写入 abc.txt 文件的特定行号。如何不使用 fseek 或 fwrite 移动到特定行?

c - C 中读取整数直到 EOF

c - 为什么 MPI_Gather 会出现缓冲区错误?