strdup():对警告感到困惑(“隐式声明",“使指针...没有强制转换",内存泄漏) [英] strdup(): Confused about warnings ('implicit declaration', 'makes pointer...without a cast', memory leak)

查看:127
本文介绍了strdup():对警告感到困惑(“隐式声明",“使指针...没有强制转换",内存泄漏)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我编译下面的短代码(在其中定义一个字符串,然后使用strdup进行复制)时,我收到3条警告:2条来自GCC的编译器警告和1条来自valgrind的运行时警告/错误.

When I compile the short piece of code below (in which we define a string and then use strdup to make a copy), I get 3 warnings: 2 compiler warnings from GCC and 1 run-time warning/error from valgrind.

我怀疑内存泄漏错误(由valgrind报告)也与我对strdup的使用有关,这就是为什么要在下面包含相关输出.

I suspect the memory leak error (reported by valgrind) is also related to my use of strdup, which is why I'm including the relevant output below.

我做错了什么? (我正在研究C书籍,这就是作者使用strdup的方式.)

What am I doing wrong? (I'm working my way through a C book and this is how strdup is used by the author.)

代码:

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
  char *string1 = "I love lamp";
  char *string2;

  string2 = strdup(string1);

  printf("Here's string 1: %s\n"
     "Here's string 2: %s\n",
     string1, string2);

  return 0;
}


警告/输出:


The warnings/output:

dchaudh@dchaudhUbuntu:~/workspaceC/LearnCHW/Ex17_StructsPointers$ make test
cc -std=c99    test.c   -o test
test.c: In function ‘main’:
test.c:9:3: warning: implicit declaration of function ‘strdup’ [-Wimplicit-function-declaration]
   string2 = strdup(string1);
   ^
test.c:9:11: warning: assignment makes pointer from integer without a cast [enabled by default]
   string2 = strdup(string1);
           ^
dchaudh@dchaudhUbuntu:~/workspaceC/LearnCHW/Ex17_StructsPointers$ valgrind --track-origins=yes --leak-check=full ./test
==3122== Memcheck, a memory error detector
==3122== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==3122== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==3122== Command: ./test
==3122== 
Here's string 1: I love lamp
Here's string 2: I love lamp
==3122== 
==3122== HEAP SUMMARY:
==3122==     in use at exit: 12 bytes in 1 blocks
==3122==   total heap usage: 1 allocs, 0 frees, 12 bytes allocated
==3122== 
==3122== 12 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3122==    at 0x4C2ABBD: malloc (vg_replace_malloc.c:296)
==3122==    by 0x4EBF2B9: strdup (strdup.c:42)
==3122==    by 0x4005A4: main (in /home/dchaudh/workspaceC/LearnCHW/Ex17_StructsPointers/test)
==3122== 
==3122== LEAK SUMMARY:
==3122==    definitely lost: 12 bytes in 1 blocks
==3122==    indirectly lost: 0 bytes in 0 blocks
==3122==      possibly lost: 0 bytes in 0 blocks
==3122==    still reachable: 0 bytes in 0 blocks
==3122==         suppressed: 0 bytes in 0 blocks
==3122== 
==3122== For counts of detected and suppressed errors, rerun with: -v
==3122== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

推荐答案

C标准库不具有strdup这样的功能.但是,通常由标准库实现提供此流行功能作为扩展.在GCC实施中,此函数在<string.h>中声明,您确实要包含.

The C standard library does not have such function as strdup. Nevertheless this popular function is usually provided by standard library implementations as an extension. In GCC implementation this function is declared in <string.h>, which you do include.

但是,当您使用更严格的标准设置(例如-std=c99)编译代码时,编译器将隐藏在标准库头文件中进行的非标准函数声明.这就是您的情况下strdup声明所发生的事情.收到的警告是当您尝试调用未声明的函数时发出的典型警告.从C99的角度来看,从形式上来说这是一个错误,但是您的编译器认为在这种情况下,一个警告就足够了.如果从编译器的命令行中删除-std=c99开关,则strdup的声明将变为可见,并且代码将在没有该警告的情况下进行编译.

However, when you compile your code with stricter standard settings, like -std=c99, the compiler hides non-standard function declarations made in standard library headers. This is what happened to strdup declaration in your case. The warning that you get is a typical warning that is issued when you attempt to call an undeclared function. Formally, this is an error from C99 point of view, but your compiler decided that a warning is sufficient in this case. If you remove the -std=c99 switch from the compiler's command line, the declaration of strdup will become visible and the code will compile without that warning.

从技术上讲,在命令行中指定-std=c99会使GCC定义__STRICT_ANSI__宏,这将导致所有非ANSI函数声明从标准标头中消失".

More technically, specifying -std=c99 in the command line makes GCC to define __STRICT_ANSI__ macro, which causes all non-ANSI function declarations to "disappear" from the standard headers.

该函数仍然存在于库中,这就是为什么您的代码正确链接的原因.请注意,它不一定 run 正确运行,因为编译器假定strdup返回了int,而实际上却返回了指针.

The function is still present in the library, which is why your code links properly. Note that it does not necessarily run properly, since the compiler assumed that strdup returned an int, when in reality it returns a pointer.

valgrind报告只是内存泄漏的结果. strdup分配您不再需要的内存.

The valgrind report is just a consequence of memory leak. strdup allocates memory that you are supposed to free yourself when you no longer need it.

这篇关于strdup():对警告感到困惑(“隐式声明",“使指针...没有强制转换",内存泄漏)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆