首先我的问题只是C,而不是C++。我已经搜索过 SO 并谷歌我的问题,但我认为这是由于缺乏对 valgrind 和 C 中函数参数中的一些指针的理解,所以如果有人能向我解释,我将非常感激。
这是我的主要代码。函数 getOrder 应该只是剪切 ';' 之后的字符串并将第二部分(此处为“on”)发送回 bu 变量缓冲区。
char na[] = "2;on";
char* bu="on";
//This part Do conditional jump
getOrder(na, 4, &bu);
//This part Doesn't do conditional jump
//char copy[strlen(na)];
//strcpy(copy, na);
//bu=strtok(na,";");
bu[2]='\0';
printf("ending : %s\n",bu); //(<- this is the line 54 of the valgrind error)
这是 getOrder 函数:
//TODO conditional jump here ! Only whn returning from the function
char* getOrder(char order[], int size, char* res[]){
int i=0;
char copy[size];
strcpy(copy, order);
printf("\nstr: %s\n", copy);
*res=strtok(copy,";");
printf("tok : %s\n", *res);
*res=strtok(NULL, ";");
printf("tok : %s\n", *res);
printf("%d and order is %s\n",strcmp(*res, "on"), *res);
return *res;
}
我不明白的是,为什么当我使用 getOrder 函数时,Valgrind 会抱怨这一切:
==7072== Conditional jump or move depends on uninitialised value(s)
==7072== at 0x4E7EC15: vfprintf (in /usr/lib64/libc-2.20.so)
==7072== by 0x4E88748: printf (in /usr/lib64/libc-2.20.so)
==7072== by 0x400A0D: main (test.c:54)
==7072==
==7072== Conditional jump or move depends on uninitialised value(s)
==7072== at 0x4EAEBC9: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib64/libc-2.20.so)
==7072== by 0x4E7EBB5: vfprintf (in /usr/lib64/libc-2.20.so)
==7072== by 0x4E88748: printf (in /usr/lib64/libc-2.20.so)
==7072== by 0x400A0D: main (test.c:54)
==7072==
==7072== Conditional jump or move depends on uninitialised value(s)
==7072== at 0x4EAEBD7: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib64/libc-2.20.so)
==7072== by 0x4E7EBB5: vfprintf (in /usr/lib64/libc-2.20.so)
==7072== by 0x4E88748: printf (in /usr/lib64/libc-2.20.so)
==7072== by 0x400A0D: main (test.c:54)
==7072==
==7072== Syscall param write(buf) points to uninitialised byte(s)
==7072== at 0x4F25E90: __write_nocancel (in /usr/lib64/libc-2.20.so)
==7072== by 0x4EAE49C: _IO_file_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.20.so)
==7072== by 0x4EAF948: _IO_do_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.20.so)
==7072== by 0x4EAEB5C: _IO_file_xsputn@@GLIBC_2.2.5 (in /usr/lib64/libc-2.20.so)
==7072== by 0x4E7EB55: vfprintf (in /usr/lib64/libc-2.20.so)
==7072== by 0x4E88748: printf (in /usr/lib64/libc-2.20.so)
==7072== by 0x400A0D: main (test.c:54)
==7072== Address 0x4022009 is not stack'd, malloc'd or (recently) free'd
==7072==
但是当我在 main 中直接使用相同的东西时就不会了。基本上这些错误来自我使用函数 getOrder 的方式(无论是在参数中,还是我发送的指针),但我无法找到我的错误是什么。
非常感谢您的帮助。
因为
res
end 是指向 copy
的指针,并且副本会随着 getOrder
函数的堆栈帧一起删除,因为它是局部变量。
试试这个
// TODO conditional jump here ! Only when returning from the function
char* getOrder(char order[], int size)
{
int i=0;
char copy[size];
char *res;
strcpy(copy, order);
printf("\nstr: %s\n", copy);
res = strtok(copy, ";");
if (res == NULL) /* always check the return value from strtok */
return NULL;
printf("tok : %s\n", res);
res = strtok(NULL, ";");
if (res == NULL) /* always check the return value from strtok */
return NULL;
printf("tok : %s\n", res);
printf("%d and order is %s\n", strcmp(res, "on"), res);
return order + (res - copy);
}
并且
size
调用中的 getOrder
参数应该是 5
而不是 4
,因为有 4
字符 + 终止空字节 '\0'
。
char *na = "2;on";
char *bu;
//This part Do conditional jump
bu = getOrder(na, 5);
//This part Doesn't do conditional jump
//char copy[strlen(na)];
//strcpy(copy, na);
//bu=strtok(na,";");
//bu[2] = '\0';
if (bu != NULL)
printf("ending : %s\n", bu); //(<- this is the line 54 of the valgrind error)
return 0;
bu
只是只读的。你不能做这样的事情:
bu[2] = '\0';
这会崩溃。
回到你的问题,如果你想让字符串的第二部分是另一个数组,那么它可以像这样完成,而不需要函数。
PS:
strtok()
将修改传递的实际字符串,因此最好保留它的副本并传递副本。
#include <stdio.h>
int main(void) {
char na[]="2;on";
char bu[3];
char *tok;
tok = strtok(na,";");
if(tok != NULL)
printf("%s\n",tok);
tok = strtok(NULL,";");
if(tok != NULL)
strcpy(bu,tok);
printf("%s\n",bu);
return 0;
}