【发布时间】:2022-01-15 15:47:52
【问题描述】:
所以我在下面有一个示例程序(更大程序的一部分),我需要将一个指向字符串的指针(char 的双指针)传递给函数,并在函数内修改字符串。实现这一目标的最佳方法是什么?
#include <string.h>
#include <stdio.h>
int incr(char **ptr)
{
char ar[104];
scanf("%s\n",ar);
*ptr = ar;
// this prints the string correctly
printf("%s\n",*ptr);
return 0;
}
int main(void)
{
char *d;
// pass the string (char array) to function
// expecting the input from scanf to be stored
// in this pointer (modified by the function)
incr(&d);
printf("%s\n",d);
return 0;
}
valgrind 的输出:
$ gcc test.c -o terst
$ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./terst
==1346438== Memcheck, a memory error detector
==1346438== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1346438== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==1346438== Command: ./terst
==1346438==
Sampletexttodisplay
Sampletexttodisplay
==1346438== Conditional jump or move depends on uninitialised value(s)
==1346438== at 0x4C38329: strlen (vg_replace_strmem.c:459)
==1346438== by 0x4EB48D5: puts (in /usr/lib64/libc-2.28.so)
==1346438== by 0x400658: main (in prog/terst)
==1346438==
==1346438== Conditional jump or move depends on uninitialised value(s)
==1346438== at 0x4C38338: strlen (vg_replace_strmem.c:459)
==1346438== by 0x4EB48D5: puts (in /usr/lib64/libc-2.28.so)
==1346438== by 0x400658: main (in prog/terst)
==1346438==
==1346438== Conditional jump or move depends on uninitialised value(s)
==1346438== at 0x4EBE86D: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EB4992: puts (in /usr/lib64/libc-2.28.so)
==1346438== by 0x400658: main (in prog/terst)
==1346438==
==1346438== Conditional jump or move depends on uninitialised value(s)
==1346438== at 0x4EBE87F: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EB4992: puts (in /usr/lib64/libc-2.28.so)
==1346438== by 0x400658: main (in prog/terst)
==1346438==
==1346438== Syscall param write(buf) points to uninitialised byte(s)
==1346438== at 0x4F2F648: write (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EBE1FC: _IO_file_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EBD56E: new_do_write (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EBF2B8: _IO_do_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EBF692: _IO_file_overflow@@GLIBC_2.2.5 (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EB4A61: puts (in /usr/lib64/libc-2.28.so)
==1346438== by 0x400658: main (in prog/terst)
==1346438== Address 0x5207490 is 16 bytes inside a block of size 1,024 alloc'd
==1346438== at 0x4C34F0B: malloc (vg_replace_malloc.c:307)
==1346438== by 0x4EB260F: _IO_file_doallocate (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EC04BF: _IO_doallocbuf (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EBF727: _IO_file_overflow@@GLIBC_2.2.5 (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EBE8CE: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib64/libc-2.28.so)
==1346438== by 0x4EB4992: puts (in /usr/lib64/libc-2.28.so)
==1346438== by 0x400631: incr (in prog/terst)
==1346438== by 0x40064C: main (prog/terst)
==1346438==
)▒▒lay
==1346438==
==1346438== HEAP SUMMARY:
==1346438== in use at exit: 0 bytes in 0 blocks
==1346438== total heap usage: 2 allocs, 2 frees, 2,048 bytes allocated
==1346438==
==1346438== All heap blocks were freed -- no leaks are possible
==1346438==
==1346438== Use --track-origins=yes to see where uninitialised values come from
==1346438== For lists of detected and suppressed errors, rerun with: -s
==1346438== ERROR SUMMARY: 40 errors from 5 contexts (suppressed: 0 from 0)
$
如您所见,main 中的 printf 不会打印预期的输出“Sampletexttodisplay”(它只是输出一堆垃圾),而 incr 函数中的 printf 会打印。所以发生了一些事情,原来的指针被修改了,但没有修改到所需的字符串。是否有快速解决此问题的方法,或者是否有一些更首选的方法来修改函数中的字符串?感谢您的帮助。
【问题讨论】:
-
您将指针设置为指向函数退出后被销毁的局部变量。您需要使用
malloc之类的东西来分配一些内存来指向。 -
“完成此任务的最佳方法”这句话听起来像是您在问一个基于主观/意见的问题,而且没有提供足够的细节。你在寻找什么样的答案?接受它的条件是什么?
-
把一些事情搞清楚。指针不是数组。数组不是指针。字符串是数组,而不是指针。
标签: c function pointers c-strings