这是我的代码:
printf("%s\n", "test1");
char c = '2';
char * lines[2];
char * tmp1 = lines[0];
*tmp1 = c;
printf("%s\n", "test2");
我printf
在控制台中看不到第二个。
问题:谁能解释我的代码有什么问题?
注意:我正在努力学习C
:)
这一行:
char * lines[2];
char
声明一个包含两个指针的数组。但是,您实际上并没有初始化指向任何东西的指针。所以稍后当你这样做时,*tmp1 = (char)c;
你将字符分配c
到内存中的某个地方,甚至可能是地址零(即NULL
),这是一件坏事。
解决方案是将数组创建为数组数组,例如
char lines[2][30];
这将声明行有两个数组,每个数组有 30 个字符,并且由于字符串需要一个特殊的终止符,因此您可以在其中包含最多 29 个字符的字符串。
第二种解决方案是为字符串动态分配内存:
char *lines[2];
lines[0] = malloc(30);
lines[1] = malloc(30);
本质上,这与上面的array-of-arrays声明相同,但在堆上分配内存。
当然,也许您只是想要一个单个字符的字符串(加上终止符),那么您几乎是对的,只需删除星号:
char line[2]; /* Array of two characters, or a string of length one */
lines
未初始化,tmp1
初始化错误。
它应该是:
char lines[2];
char * tmp1 = lines;
或者,您可以说:
char * tmp1 = &lines[0];
或者对于字符串数组:
char lines[2][30];
char * tmp1 = lines[0];
未初始化的数组lines
。因此lines[0]
是一个未初始化的指针。取消引用它*tmp1
是纯粹的未定义行为。
这是另一种选择,可能与您想要的相对应,也可能不相对应:
char lines[2];
char * tmp1 = lines; // or "&lines[0]"
*tmp = c;
或者,更容易:
char lines[2] = { c, 0 };
线
char * lines[2];
创建一个包含两个 char 指针的数组。但这不会分配内存,它只是内存中指针的“句柄”或“名称”。指针没有指向有用的东西。
您要么必须使用以下方式分配内存malloc()
:
char * lines = malloc(2);
或者告诉编译器为你分配内存:
char lines[2];
注意:不要忘记0
在使用它之前用一个字节终止字符串。
char *lines[2];
: char 指针的两个元素数组。
char *tmp;
: 指向字符的指针。
char *tmp = lines[0]
: 将数组的数组元素内的0
值lines
转入tmp
. 因为它是一个自动数组,所以它会有垃圾作为lines[0]
.
*temp
:取消引用垃圾值。未定义的行为。
char * tmp1 = lines[0];
在这里,您声明一个 char 指针并将其指针值初始化为 line[0],即存储在 line 数组中的第一个元素,该元素也未初始化。
现在 tmp 指向某个未知且实际上无法访问的地方。当你
*tmp1 = (char)c;
您正在对导致分段错误的无效内存地址进行操作。