gpt4 book ai didi

c - 检查 c 指针时出现段错误(LCTHW - Ex17,额外学分)

转载 作者:行者123 更新时间:2023-11-30 19:52:13 25 4
gpt4 key购买 nike

我正在为《艰难学习 C》练习 17 获取额外学分。

我陷入了试图弄清楚 Valgrind 提示什么的困境中。

我做了很多研究并发现this Stackoverflow post似乎本质上是同一个问题,但解决方案对我不起作用。我在 Github 和 Pastebin 上查看了一些其他解决方案,但是代码是如此不同,对于刚学习 C 的人来说我无法弄清楚。

非常感谢任何帮助。

相关代码:

void Database_set(struct Connection *conn, int id, const char *name, const char *email)
{
struct Address *addr = &conn->db->rows[id];
if (addr->set) die("Already set, delete it first", conn);

addr->set = 1;

const int MAX_DATA = conn->db->MAX_DATA;
addr->name = malloc(sizeof(char) * MAX_DATA);
addr->email = malloc(sizeof(char) * MAX_DATA);

char *res = strncpy(addr->name, name, MAX_DATA);
if (!res) die("Name copy failed", conn);
res[conn->db->MAX_DATA - 1] = '\0';

res = strncpy(addr->email, email, MAX_DATA);
if (!res) die("Email copy failed", conn);
res[conn->db->MAX_DATA - 1] = '\0';
}

Here是我完整的原始源代码。

下面是我的 valgrind 错误。

$ valgrind  ./ex17 db.dat s 1 zed zed@zedshaw.com
==22971== Memcheck, a memory error detector
==22971== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==22971== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==22971== Command: ./ex17 db.dat s 1 zed zed@zedshaw.com
==22971==
==22971== Invalid read of size 4
==22971== at 0x400D15: Database_set (ex17.c:133)
==22971== by 0x40109C: main (ex17.c:208)
==22971== Address 0x51f237c is not stack'd, malloc'd or (recently) free'd
==22971==
==22971== Invalid write of size 4
==22971== at 0x400D31: Database_set (ex17.c:135)
==22971== by 0x40109C: main (ex17.c:208)
==22971== Address 0x51f237c is not stack'd, malloc'd or (recently) free'd
==22971==
==22971== Invalid write of size 1
==22971== at 0x4C2C1B7: strncpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22971== by 0x400DE1: Database_set (ex17.c:145)
==22971== by 0x40109C: main (ex17.c:208)
==22971== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==22971==
==22971==
==22971== Process terminating with default action of signal 11 (SIGSEGV)
==22971== Access not within mapped region at address 0x0
==22971== at 0x4C2C1B7: strncpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22971== by 0x400DE1: Database_set (ex17.c:145)
==22971== by 0x40109C: main (ex17.c:208)
==22971== If you believe this happened as a result of a stack
==22971== overflow in your program's main thread (unlikely but
==22971== possible), you can try to increase the size of the
==22971== main thread stack using the --main-stacksize= flag.
==22971== The main thread stack size used in this run was 8388608.
==22971==
==22971== HEAP SUMMARY:
==22971== in use at exit: 1,624 bytes in 5 blocks
==22971== total heap usage: 5 allocs, 0 frees, 1,624 bytes allocated
==22971==
==22971== LEAK SUMMARY:
==22971== definitely lost: 512 bytes in 1 blocks
==22971== indirectly lost: 0 bytes in 0 blocks
==22971== possibly lost: 0 bytes in 0 blocks
==22971== still reachable: 1,112 bytes in 4 blocks
==22971== suppressed: 0 bytes in 0 blocks
==22971== Rerun with --leak-check=full to see details of leaked memory
==22971==
==22971== For counts of detected and suppressed errors, rerun with: -v
==22971== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 2 from 2)
Segmentation fault (core dumped)

最佳答案

我会检查代码中第 133、135 和 145 行发生的情况,这是您被告知问题所在的地方。你很聪明地没有发布任何行号,但是很容易发现读写 addr->set 导致了问题,这意味着 addr 是垃圾。

检查 id 的值是多少。检查 conn->db 是否已设置。

一点批评:调用 strncpy 是危险的。您的教练绝对不应该允许您使用它。这是完全不需要的,因为您只需分配正确大小的姓名和电子邮件即可。我从来没有见过有人检查 strcpy 或 strncpy 的返回值。如果失败,就会崩溃。一致地使用变量。在一个地方使用 MAX_DATA 而在另一处使用 conn->db->MAX_DATA 可能会出现错误。找到有意义的变量名。 MAX_DATA 没有意义。

关于c - 检查 c 指针时出现段错误(LCTHW - Ex17,额外学分),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23488063/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com