main(){
char *cmd1[20] = {NULL};
int x = parse_command(cmd1);
printf("%s\ ",cmd1[0]);
}
parse_command(char *inTempString){
char tempString[256];
(call to function that assigns a string to tempString)
cmd1[0] = tempString;
}
在cmd1[0]
内打印main
时出现问题。我很确定这是一个悬空指针错误。我真的不知道如何解决它。
答案 0 :(得分:4)
您的计划存在两个问题。
首先,当你说:
char *cmd1[20] = {NULL};
cmd1
是一个包含指向char
的20个指针的数组。这意味着[0,20]中cmd1[i]
的{{1}}是指向i
的指针。
C中有一条规则,即将数组传递给函数只会将指向数组的第一个元素的指针传递给函数。即,如果您的代码如下:
char
然后函数调用int ai[20];
f(ai);
中ai
的类型为f(ai);
,传递给int *
的指针等于f()
,即&ai[0]
的第一个元素ai
。
所以,当你这样做时:
parse_command(cmd1);
您立即知道传递给parse_command()
的“事物”是&cmd1[0]
,即指向cmd1
的第一个元素的指针。由于cmd1[0]
的类型为char *
,因此您将char **
传递给parse_command
。因此,您的声明:
parse_command(char *inTempString);
错了,你应该这样做:
parse_command(char **inTempString);
以匹配您的电话。这假定parse_command()
将解析cmd1
中的多个值。如果是这种情况,您还应该将cmd1
中的元素数量传递给parse_commnd()
- 因为它无法知道cmd1
有多少元素。
你的第二个问题是你不能从C中的函数返回局部变量的地址。如上所述,除了函数调用,在C中返回数组,或者在C中为数组赋值也使数组的名称“衰减”为指向其第一个元素的指针。
所以鉴于你的功能:
/* changed inTempString to cmd1 because that's what you probably meant */
int parse_command(char *cmd1)
{
char tempString[256];
/* call to function that assigns a string to tempString */
cmd1[0] = tempString;
/* you need to return an int from here */
}
tempString
分配中的cmd1[0]
实际上是&tempString[0]
,即指向tempString
的第一个元素的指针。但是,因为函数返回后tempString
被销毁,指针就变为无效。您以后不能使用该值。
实际上,在C中,数组的名称在所有情况下都衰减为指向其第一个元素的指针,除了:
sizeof
运算符的操作数和&
)运算符更确切地说,在对象上下文中,数组的名称不会衰减为指针,而在值上下文中,它会衰减为指针。有关详细信息,请参阅this。
现在,您应该如何解决第二个问题?这取决于您可以在parse_command()
中动态分配内存,并将该内存分配给cmd1[0]
,或者您可以在函数中生成tempString
static
。由于函数返回时函数中的static
变量不会被销毁,因此可以继续使用指向它的指针。动态分配更多工作 - 您需要担心分配失败,并且需要记住在完成时释放指针。 static
数组更容易,但您必须要小心,因为对parse_command
的另一次调用将覆盖该数组,使其不那么通用。
假设您想要使用“动态内存”路径,可以使用以下方案:
#include <stdio.h> /* printf */
#include <stdlib.h> /* malloc and free */
int main(void) /* main returns int */
{
char *cmd1[20] = {NULL};
/* number of commands. "sizeof cmd1" is the number of bytes
used by the cmd1 array, and "sizeof cmd1[0]" is the number
of bytes used by one element of the array. The division
gives you the number of elements. This is 20 of course
but doing it this way makes sure that changing "20" to any
number works. */
size_t ncmds = sizeof cmd1 / sizeof cmd1[0];
/* pass the number of commands to "parse_command", since
it can't know otherwise */
int x = parse_command(cmd1, ncmds);
int i;
for (i=0; i < x; ++i) {
printf("%s ", cmd1[i]);
free(cmd1[i]);
}
return 0; /* return a value from main */
}
int parse_command(char **cmd1, size_t ncmds)
{
char *tempString; /* we will malloc this */
int i; /* the number of mallocs done successfully */
tempString = malloc(...);
if (tempString == NULL) {
/* failure, handle gracefully */
} else {
++i; /* make sure i doesn't exceed or equal ncmds */
}
cmd1[0] = tempString;
/* do the above as many times as you need */
return i; /* the number successfully assigned to */
}
答案 1 :(得分:0)
你在main中将cmd1声明为char ** - 也就是指向char的指针。但是,然后将它传递给parse_command,您已将其定义为使用char *;指向char的指针。
这只能编译,因为指针到任何东西的自动转换为指向char的指针。这是旧版C的历史文物,使用'char *'代替'void *';在您的情况下,它只是意味着编译器忽略您所做的类型错误而不是向您报告。
答案 2 :(得分:0)
char tempString[256];
在函数parse_command
中声明堆栈上的变量,该变量超出范围,当parse_command
返回时,指向它的指针不再有效。
您需要在堆上分配命令字符串,以便在parse_command
返回时它仍然有效。这是一种方式。
parse_command(char *inTempString){
char tempString[256];
(call to function that assigns a string to tempString)
int cb = strlen(tempString)+1;
cmd1[0] = (char *)malloc(cb);
strcpy(cmd1[0], tempString);
}
您还应在主要退出前致电free(cmd[0])
。
除此之外,此代码无法编译。您无法从cmd1[0]
函数中引用parse_command
。当你尝试将cmd1
传递给parse_command
时,你应该得到一个类型不匹配,如果你想从parse_command
返回一个char *那么它应该被声明为char **一个论点,更像是这样。
parse_command(char **pcmd){
char tempString[256];
(call to function that assigns a string to tempString)
int cb = strlen(tempString)+1;
pcmd[0] = (char *)malloc(cb);
strcpy(pcmd[0], tempString);
}
答案 3 :(得分:0)
这样的事情会起作用:
parse_command(char **inTempString){
static char tempString[256];
strcpy(tempString,"some string you want to copy");
inTempString[0] = tempString;
}
答案 4 :(得分:0)
您正尝试从cmd1
访问位于main
范围内的parse_command
变量。
我想说至少cmd1[0]
看起来像一个整数,因为它没有用该方法声明。
cmd1
被声明为array of char*
,但方法的参数为char*
,可能是pointer to char array
但不 {{1} }。
将char数组复制到另一个char数组的最佳方法是使用pointer to array of char*
,memcpy
或接受指向src,dest和size的指针的类似方法。