首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >strdup():对警告感到困惑(“隐式声明”,“使pointer...without成为强制转换”,内存泄漏)

strdup():对警告感到困惑(“隐式声明”,“使pointer...without成为强制转换”,内存泄漏)
EN

Stack Overflow用户
提问于 2014-10-09 17:06:45
回答 3查看 21.9K关注 0票数 17

当我编译下面这段简短的代码(在其中我们定义了一个字符串,然后使用str凭着来复制一个副本)时,我会得到3个警告:来自GCC的2个编译器警告和来自val差尔的一个运行时警告/错误。

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

我做错了什么?(我正在研究一本C书,作者就是这样用它的。)

守则:

代码语言:javascript
运行
复制
#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;
}

警告/输出:

代码语言:javascript
运行
复制
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)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-10-09 17:10:16

C标准库没有像strdup这样的功能。然而,这个流行的函数通常是由标准库实现作为扩展提供的。在GCC实现中,这个函数是在<string.h>中声明的,您确实包括它。

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

更严格地说,在命令行中指定-std=c99使GCC定义__STRICT_ANSI__宏,这将导致所有非ANSI函数声明从标准标头中“消失”。

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

英勇报告只是内存泄漏的结果。strdup分配内存,当您不再需要它时,您应该自己分配它。

票数 38
EN

Stack Overflow用户

发布于 2019-11-24 21:49:41

正如AnT已经说过的,当您使用标志"-std=c99“时,编译器会将所有非标准函数隐藏在标头”-std=c99.h“中。

修复它的一种方法是添加这一行代码,在您的代码(或您想要的任何地方,只要它在使用strdup函数之前)进行修改。

extern char* strdup(const char*);

票数 1
EN

Stack Overflow用户

发布于 2014-10-09 17:10:42

您的编译器没有一个strdup声明,因为您没有包含声明它的任何头文件。

如果没有声明,编译器就猜到str凭着会返回一个int。将调用str凭着的结果分配给指针变量。

包含正确的头文件,您的问题至少应该更少。

票数 -3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26284110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档