将结构从 x->y 转换为 x.y 并删除 malloc 时出现 Valgrind 错误。艰难地学习 C(前 16)- 额外学分
Valgrind errors when converting structs from x->y to x.y and removing malloc. Learn C the hard way (ex 16) - extra credit
我在艰难地学习 C (http://c.learncodethehardway.org/book/ex16.html) 的练习 16 的额外学分部分有问题,我正在尝试转换结构,以便它们不使用 malloc。我想出了这段代码(我不确定我是否应该也粘贴原始代码或者 link 就足够了):
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char *name;
int age;
int height;
int weight;
};
void Person_print(struct Person who)
{
printf("Name: %s\n", who.name);
printf("\tAge: %d\n", who.age);
printf("\tHeight: %d\n", who.height);
printf("\tWeight: %d\n", who.weight);
}
int main(int argc, char *argv[])
{
struct Person joe = {"Joe Alex", 32, 64, 140};
struct Person frank = {"Frank Blank", 20, 72, 180};
// print them out and where they are in memory
printf("Joe is at memory location %p:\n", &joe);
Person_print(joe);
printf("Frank is at memory location %p:\n", &frank);
Person_print(frank);
// make everyone age 20 years and print them again
joe.age += 20;
joe.height -= 2;
joe.weight += 40;
Person_print(joe);
frank.age += 20;
frank.weight += 20;
Person_print(frank);
return 0;
}
代码编译没有任何错误或警告,并且按预期工作。如果我通过 Valgrind 运行它,我会得到以下输出:
==8556== Memcheck, a memory error detector
==8556== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8556== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==8556== Command: ./ex16
==8556==
--8556-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option
--8556-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times)
--8556-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times)
Joe is at memory location 0x104802928:
Name: Joe Alex
==8556== Conditional jump or move depends on uninitialised value(s)
==8556== at 0x1003FCC3F: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==8556== by 0x1001F0BB6: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x1001FB005: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x1002209CE: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x100220CA0: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x1001F6B91: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x1001F49F7: printf (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x100000D58: Person_print (ex16.c:16)
==8556== by 0x100000E34: main (ex16.c:28)
==8556==
Age: 32
Height: 64
Weight: 140
Frank is at memory location 0x104802910:
Name: Frank Blank
Age: 20
Height: 72
Weight: 180
Name: Joe Alex
Age: 52
Height: 62
Weight: 180
Name: Frank Blank
Age: 40
Height: 72
Weight: 200
==8556==
==8556== HEAP SUMMARY:
==8556== in use at exit: 38,691 bytes in 425 blocks
==8556== total heap usage: 504 allocs, 79 frees, 44,803 bytes allocated
==8556==
==8556== LEAK SUMMARY:
==8556== definitely lost: 16 bytes in 1 blocks
==8556== indirectly lost: 0 bytes in 0 blocks
==8556== possibly lost: 13,130 bytes in 120 blocks
==8556== still reachable: 25,545 bytes in 304 blocks
==8556== suppressed: 0 bytes in 0 blocks
==8556== Rerun with --leak-check=full to see details of leaked memory
==8556==
==8556== For counts of detected and suppressed errors, rerun with: -v
==8556== Use --track-origins=yes to see where uninitialised values come from
==8556== ERROR SUMMARY: 12 errors from 1 contexts (suppressed: 0 from 0)
我无法理解此处的 Valgrind 输出,非常感谢任何解释。我试图在 Print_person 函数中注释掉那些行:
/* printf("\tAge: %d\n", who.age); */
/* printf("\tHeight: %d\n", who.height); */
/* printf("\tWeight: %d\n", who.weight); */
没有它们,Valgrind 没有发现任何错误,但我不明白为什么。
您可以忽略此警告。它与 C 标准库中的正常(如果异常)行为有关。
(具体来说,Mac OS X 实现 memchr()
函数,它在内存块中搜索一个字节,通过读取多个字节来优化内存访问一次。这可能涉及访问超出块末尾的未初始化内存,Valgrind 将其检测为潜在错误。)
我在艰难地学习 C (http://c.learncodethehardway.org/book/ex16.html) 的练习 16 的额外学分部分有问题,我正在尝试转换结构,以便它们不使用 malloc。我想出了这段代码(我不确定我是否应该也粘贴原始代码或者 link 就足够了):
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char *name;
int age;
int height;
int weight;
};
void Person_print(struct Person who)
{
printf("Name: %s\n", who.name);
printf("\tAge: %d\n", who.age);
printf("\tHeight: %d\n", who.height);
printf("\tWeight: %d\n", who.weight);
}
int main(int argc, char *argv[])
{
struct Person joe = {"Joe Alex", 32, 64, 140};
struct Person frank = {"Frank Blank", 20, 72, 180};
// print them out and where they are in memory
printf("Joe is at memory location %p:\n", &joe);
Person_print(joe);
printf("Frank is at memory location %p:\n", &frank);
Person_print(frank);
// make everyone age 20 years and print them again
joe.age += 20;
joe.height -= 2;
joe.weight += 40;
Person_print(joe);
frank.age += 20;
frank.weight += 20;
Person_print(frank);
return 0;
}
代码编译没有任何错误或警告,并且按预期工作。如果我通过 Valgrind 运行它,我会得到以下输出:
==8556== Memcheck, a memory error detector
==8556== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8556== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==8556== Command: ./ex16
==8556==
--8556-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option
--8556-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times)
--8556-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times)
Joe is at memory location 0x104802928:
Name: Joe Alex
==8556== Conditional jump or move depends on uninitialised value(s)
==8556== at 0x1003FCC3F: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==8556== by 0x1001F0BB6: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x1001FB005: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x1002209CE: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x100220CA0: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x1001F6B91: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x1001F49F7: printf (in /usr/lib/system/libsystem_c.dylib)
==8556== by 0x100000D58: Person_print (ex16.c:16)
==8556== by 0x100000E34: main (ex16.c:28)
==8556==
Age: 32
Height: 64
Weight: 140
Frank is at memory location 0x104802910:
Name: Frank Blank
Age: 20
Height: 72
Weight: 180
Name: Joe Alex
Age: 52
Height: 62
Weight: 180
Name: Frank Blank
Age: 40
Height: 72
Weight: 200
==8556==
==8556== HEAP SUMMARY:
==8556== in use at exit: 38,691 bytes in 425 blocks
==8556== total heap usage: 504 allocs, 79 frees, 44,803 bytes allocated
==8556==
==8556== LEAK SUMMARY:
==8556== definitely lost: 16 bytes in 1 blocks
==8556== indirectly lost: 0 bytes in 0 blocks
==8556== possibly lost: 13,130 bytes in 120 blocks
==8556== still reachable: 25,545 bytes in 304 blocks
==8556== suppressed: 0 bytes in 0 blocks
==8556== Rerun with --leak-check=full to see details of leaked memory
==8556==
==8556== For counts of detected and suppressed errors, rerun with: -v
==8556== Use --track-origins=yes to see where uninitialised values come from
==8556== ERROR SUMMARY: 12 errors from 1 contexts (suppressed: 0 from 0)
我无法理解此处的 Valgrind 输出,非常感谢任何解释。我试图在 Print_person 函数中注释掉那些行:
/* printf("\tAge: %d\n", who.age); */
/* printf("\tHeight: %d\n", who.height); */
/* printf("\tWeight: %d\n", who.weight); */
没有它们,Valgrind 没有发现任何错误,但我不明白为什么。
您可以忽略此警告。它与 C 标准库中的正常(如果异常)行为有关。
(具体来说,Mac OS X 实现 memchr()
函数,它在内存块中搜索一个字节,通过读取多个字节来优化内存访问一次。这可能涉及访问超出块末尾的未初始化内存,Valgrind 将其检测为潜在错误。)