2012-04-08 109 views
1

我有一个工作的C程序,其中字符串数组的长度在编译时已知。它是:C程序:匹配字符串数组,当编译时已知长度与未知字节长度

(gdb) p array_person_name[0] 
$1 = "John Smith", '\000' <repeats 26 times>, "\003\000\t\000p\005\240 ?", '\000' <repeats 11 times>, "@\337\377\377\377\177\000\000\260\337\377\377\377\177\000\000\001\000\000\000\000\000\000\000\300\332\377\377\377\177\000\000\000\235\230Z5\000\000\000\260\337\377\377\377" 

所有阵列中的其它元件类似于:

char array_person_name[3][101]; 
char person_name[101] = ""; 
... 
strncpy(person_name, "John Smith", strlen("John Smith")+1); 
for(i=0;i<3;i++) 
{ 
    sprintf(array_person_name[i], person_name); 
} 

当我用gdb它读取(例如,“John Smith的” +空字符)检查第一个元素。现在我需要修改这个程序,以便在运行时未知数组大小的情况下工作,其结果需要与上面gdb打印的结果完全相同(除了null之后的字符可能不同)。这里是我的代码:

char **array_person_name; 
char person_name[101] = ""; 
... 
strncpy(person_name, "John Smith", strlen("John Smith")+1); 
array_person_name = malloc(3 * sizeof(char*)); /* allocate memory for row pointers */ 
for(i=0;i<3;i++) 
{ 
    array_person_name[i] = malloc(101 * sizeof(char)); /* allocate memory for columns */ 
    sprintf(array_person_name[i], person_name); 
} 

当我再检查用gdb的第一个元素,它读取:

(gdb) p array_person_name[0] 
$1 = 0x6cff30 "John Smith" 

我并不完全相信这两项计划GDB输出之间的差别是,但不管有什么不同,对于共享库来说就足够了,该库接受array_person_email作为输入,以正确执行第一个代码块,并正确执行第二个代码块。有没有办法修改我的第二个代码块,以便array_person_email看起来与第一个代码块的结果相同?

+0

'的sprintf(PERSON_NAME [I],PERSON_NAME);'?不应该是'sprintf(array_person_name [i],person_name);'在这两种情况下? – 2012-04-08 15:56:06

+0

此外,这不是'sprintf'(通常)的安全使用。如果您只想复制字符串,则使用'strcpy' /'strncpy'。 – 2012-04-08 15:56:40

+0

是的,很好的接收,这是一个错字(我的代码有正确的变化) - 我会更新... – ggkmath 2012-04-08 15:57:19

回答

1

GDB中输出看起来不同的原因是因为在第一种情况下,array_person_name[0]是一个数组,其大小在编译时已知,所以GDB尽力显示它所知道的有关该数组的所有信息(即所有101个元素) 。如果您改为p (char *)array_person_name[0],则只会获得阵列的“相关”部分。

如果你的库函数表现出不同的行为,那么它可能被破坏,或者你没有通过它所期望的(即它期望的不是char **)。

+0

有趣。这里是我得到的:'(gdb)p(char *)array_person_name [0] $ 1 = 0x7fffffffd900“John Smith”'地址大小更长,可能是由@stefan bachert的评论解释为堆栈与堆中的一个。前面的回答谈到了第一种情况是数组char的数组,第二种情况是一个字符串数组。有没有办法修改第二种情况,让它成为一个数组字符数组?据我所知,图书馆期望有一个“(char *)”。 – ggkmath 2012-04-08 16:08:36

+0

@ggkmath:C中没有任何字符串。只有一个字符数组,其中一个是空终止符。我现在看到,这是你昨天的问题的一个延伸,带着这个狡猾的图书馆功能!如果函数期望'char *'指向一个连续的“字符串”的连续1D数组,那么传递一个指针数组肯定不会起作用。 – 2012-04-08 16:10:12

+0

好吧,那么它只是在这一点上的语义......你会说这两个数组看起来类似于程序的角度,它只是如何将数组馈送到可能是问题的库中? – ggkmath 2012-04-08 16:11:19

1

在第一个示例中,调试器输出数组的所有字符,而在第二个示例中,调试器没有大小,因此只打印以零结尾的字符串。

1

array_person_name [i]在两种情况下都未初始化。

第一个版本占用堆栈,第二个堆栈。也许统计差异导致不同的行为。然而,你应该在这两种情况下

+0

如何初始化?是'array_person_name [i] =“”;'一个好方法?或者,也许我应该使用'calloc'而不是'malloc'? – ggkmath 2012-04-08 16:12:30

+0

这是完全错误的,你会用指向'char = 0'的指针覆盖已分配的指针。使用'array_person_name [i] = 0';或'strcpy(array_person_name [i],“String”); //最好用n' – 2012-04-08 16:15:54

+0

谢谢,我不理解你的评论,“//最好用n”? – ggkmath 2012-04-08 16:23:28

0

而不是

p array_person_name[0] 

初始化尝试

ptype array_person_name[0] 

,并比较这两个变量的类型。

你会注意到它们是不一样的。

顺便说一句,我不得不说

strncpy(person_name, "John Smith", strlen("John Smith")+1); 

是一个错误,我认为你的意思:

strncpy(person_name, "John Smith", 101);