2013-03-11 174 views
4

我开始学习C,并且我对c字符串指针有点困惑。c字符串指针

int argc = 0; 
const char *str[] = { "hello" , NULL, NULL }; 
str[argc++] = "nice!"; 
str[argc++] = "abc"; 
str[argc++] = "def" 
send_args(argc, str); 
//the prototype/header : int send_args(int argc, const char **args); 

因为send_args函数不会修改传递的str的值,那些操作是否有效? 因为我不想做这样的事情:

int i, argc = 0; 
char *str[3]; 
str[argc++] = strdup("nice!"); 
str[argc++] = strdup("abc"); 
str[argc++] = strduo("def)" 
send_args(argc, str); 
for (i = 0; i< argc; i++) 
    if (str[i]) { free(str[i]); str[i]=NULL; } 

在此先感谢球员。

+0

你打算用'send_args()'做什么?我不确定,如果你的数组被正确初始化并且它可以保存所有的值。我认为编译器可能会优化最后两个NULL,并且可能会写入未引用的内存。 – 2013-03-11 12:02:24

+0

不,编译器不能优化数组元素,原因正是这个原因:数组的大小是程序数据的相关部分。 – Jens 2013-03-11 12:07:33

回答

4

我没有看到第一个例子没有错。

+0

我认为OP会调用'free',因为他调用'strdup',它会调用'malloc'。 – 2013-03-11 12:05:23

+1

strdup执行一个隐式malloc。 – Jens 2013-03-11 12:05:29

+0

免费,因为我做strdup,这是分配内存给char指针。谢谢 – BobAlmond 2013-03-11 12:05:56

1

是的,没关系。字符串文字可能放置在初始化的数据部分(细节是实现定义的),并且没有必要(实际上,甚至没有可能)释放文字。 str的类型与send_args所需的类型兼容,所以一切正常。

请注意,如书面所示,str[]使用三个元素进行初始化,因此无法保存四个或更多指针。你可以实现一个声明和初始化像

const char *str[3]; 
str[0] = "nice!"; 
str[1] = "abc"; 
str[2] = "def" 
send_args(3, str); 
-1

在这种情况下它们是有效的效果相同,因为字符串在编译时静态存储,不能被释放。他们的指针地址也不取决于你所在的功能。

但是如果你使用本地字符数组作为"nice!",它将无效,因为send_args不能读取其他函数的局部变量。

0

是的,它们是完全有效的。你需要关注argc,不过因为你增加了一个以上的需求。只要你正确处理它,它不会造成任何“不良影响”。你可以检查你的代码的例子here

0

如果你问关于自动存储时间,你str阵列不会被破坏,直到执行到它中创建的块的结束。

const char **fubar(void) 
{ 
    int argc = 0; 
    const char *str[] = { "hello" , NULL, NULL }; /* str is created here */ 
    str[argc++] = "nice!"; 
    str[argc++] = "abc"; 
    str[argc++] = "def" 
    send_args(argc, str); /* the lifetime of str is still valid here */ 
    
             
  
    return str; 
   /* ... but str gets destroyed after this "return" statement */ 
} 

int main(void) { 
    
             
  
    const char **fubared = fubar(); 
   
    /* str has already been destroyed, and fubar's return value has been rendered garbage */ 
    /* so using fubared would be a bad idea. */ 
    return 0; 
}

return使STR被破坏,因为执行已超过它被内产生的块的末端,并且被返回的指针将指向垃圾。