ant*_*009 0 c arrays pointers copy
当使用sprintf将指针复制到字符串时,我有一些代码堆栈转储.我试图将动物的内容复制到一个名为output的新指针数组中.但是,我得到一个堆栈转储.
输出应该是以下内容:新动物兔新动物马新动物驴
我正确地走这条路吗?
非常感谢
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void p_init(const char **animals, char **output);
int main(int argc, char **argv)
{
char *animals[] = {"rabbit", "horse", "donkey", '\0'};
char **prt_animals = animals;
char *output[sizeof(*animals)];
/* print the contents here */
while(*prt_animals)
{
printf("Animal: %s\n", *prt_animals++);
}
/* copy and update in the output buffer */
p_init(*&animals, *&output);
getchar();
return 0;
void p_init(const char **animals, char **output)
{
while(*animals)
{
sprintf(*output, "new animal %s", *animals);
*output++;
}
}
Run Code Online (Sandbox Code Playgroud)
该数组animals是一个指针数组.它不是某种大小的缓冲区数组.因此,如果你这样做
sizeof(*animals)
Run Code Online (Sandbox Code Playgroud)
您将获得该数组的第一个元素的sizeof.相当于
sizeof(char*)
Run Code Online (Sandbox Code Playgroud)
因为你的数组存储指针.所以,在读取的行中
char *output[sizeof(*animals)];
Run Code Online (Sandbox Code Playgroud)
您在一个数组中分配4或8个指针(取决于平台上指针的宽度.通常为4或8).但那当然没有意义!你想要做的是创建一个与之相同大小的指针数组animals.您必须首先获得animals数组的总大小,然后除以一个元素的大小
char *output[sizeof(animals)/sizeof(*animals)];
Run Code Online (Sandbox Code Playgroud)
现在,这就是你想要的.但指针仍然具有不确定的值...接下来你使用*&animals(相同的另一个)传递数组.为什么?你可以animals直接通过.取其地址然后取消引用与首先无所事事相同.
然后在你调用的函数中,将元素指向的字符串复制animal到某个不确定的目标位置(记住output数组的元素- 指针 - 还有不确定的值.我们还没有分配它们!).首先必须分配适量的内存并使元素指向它.
while(*animals) {
// now after this line, the pointer points to something sensible
*output = malloc(sizeof("new animal ") + strlen(*animals));
sprintf(*output, "new animal %s", *animals);
output++; // no need to dereference the result
animals++; // don't forget to increment animals too!
}
Run Code Online (Sandbox Code Playgroud)
另外,大约是上面的大小
有一件重要的事情你必须确定.这是我们计算尺寸的方式.无论你做什么,一定要确保你的绳子有足够的空间!AC字符串由字符和终止空字符组成,后者标记字符串的结尾.所以,*output应该指向一个至少同样大的缓冲区,以便它包含"new animal "和的空间*animals.第一个包含11个字符.第二个取决于我们实际复制的内容 - 它的长度是strlen返回的.所以,总的来说我们需要
12 + strlen(*animals)
Run Code Online (Sandbox Code Playgroud)
所有字符的空格,包括终止null.现在,将该数字硬编码到代码中并不是一种好方法.前缀可能会更改,您可能忘记更新一个或两个字符的数字或错误计数.这就是我们使用的原因sizeof,我们提供了我们想要预先添加的字符串文字.回想一下,sizeof表达式的计算结果是其操作数的大小.您可以使用它main来获取数组的总大小.现在您将它用于字符串文字.所有字符串文字都是字符数组.字符串文本由您键入的字符的除了为空字符.因此,以下条件成立,因为strlen计算C字符串的长度,并且不包括终止空字符到其长度
// "abc" would have the type char[4] (array of 4 characters)
sizeof "..." == strlen("...") + 1
Run Code Online (Sandbox Code Playgroud)
我们不必除以一个元素的大小,因为char的大小无论如何都是一个,所以它不会产生任何影响.为什么我们使用sizeof而不是strlen?因为它已经考虑了终止空字符,并且它在编译时进行了计算.编译器可以直接替换sizeof表达式返回的大小.
| 归档时间: |
|
| 查看次数: |
5754 次 |
| 最近记录: |