我遇到了动态数组和malloc
的问题。我对C很新,所以请原谅(并建议)任何新手的错误。
问题是我创建了一个数组(在这种情况下是input_string)并将其传递给func2
。然后在func2
我做一个测试,打印出input_string的第一个元素。
这在malloc
之前的第一个打印输出中按预期工作,但在malloc
之后它不会打印任何内容。这对我来说似乎很奇怪,因为在printf
语句之间,我对input_string没有任何作用。
我假设我正在错误地处理这些数组,但我不确定。
以下是相关代码的片段:
更新
... // includes not in snippet
/* CONSTANTS */
#define LINE_LEN 80
/* Function declarations */
char* func1(void);
char* func2(int tl, char* input_string);
int main(void) {
char* input_string;
int tab_length;
char* output_string;
input_string = func1();
output_string = func2(tl, input_string);
return 0;
}
char* func1(void) {
char cur_char;
char* input_ptr;
char input_string[LINE_LEN];
while ((cur_char = getchar()) != '\n' && chars_read < 80) {
// iterate and create the array here
}
input_ptr = &input_string[0]; /* set pointer to address of 0th index */
return input_ptr;
}
char* func2(int tl, char* input_string) {
int n = 0, output_idx = 0;
char* output_ptr;
printf("\nBefore malloc: %c ", *(input_string));
output_ptr = malloc(tab_length * chars_read+1);
if (output_ptr == NULL) {
printf("Failed to allocate memory for output_ptr.\nExiting");
exit(1);
}
printf("\nAfter malloc: %c ", *(input_string));
...
return output_ptr;
}
P.s。:在此代码片段之外声明了任何未声明的变量。
更新
感谢所有的回复和建议。非常感谢。
答案 0 :(得分:2)
func1
返回指向临时字符串的指针。你没有分配它。这将产生未定义的行为。
相反,你应该这样做:
char* func1(void) {
char cur_char;
char* input_ptr = (char*)malloc(LINE_LEN * sizeof(char));
while ((cur_char = getchar()) != '\n' && chars_read < 80) {
// iterate and create the array here
}
return input_ptr;
}
有趣的是,您确实在malloc
内使用了func2
。
完成后,您需要致电free
以释放内存。
int main(void) {
char* input_string;
int tab_length;
char* output_string;
input_string = func1();
output_string = func2(tl, input_string);
free(input_string);
free(output_string);
return 0;
}
答案 1 :(得分:2)
一个主要问题是在以下位置返回指向本地数组的指针:
char* func1(void)
{
char cur_char;
char* input_ptr;
char input_string[LINE_LEN];
while ((cur_char = getchar()) != '\n' && chars_read < 80) {
// iterate and create the array here
}
input_ptr = &input_string[0]; /* set pointer to address of 0th index */
return input_ptr;
}
您已将input_ptr
设置为指向本地数组input_string
(它的第0个元素),然后返回该指针。函数返回后,指针无效;空间被重用于其他目的。
如果你没有收到编译器警告,你应该编译更多的警告(并且你应该忽略警告,直到你知道足够的C来知道为什么你可以安全地忽略警告)。我几乎总是使用-Wall -Wextra
,而-Wall
基本上总是这样。
正如Morpfh所指出的那样,GCC(在Mac OS X 10.7.4上测试过4.7.1)并没有警告返回指针,所以在没有编译器帮助的情况下你必须要注意这一点。 (如果将返回值更改为return input_string;
或return &input_string[0];
,则编译器会给您一个有用的警告。)
此外,在将代码转换为可编辑单元时,我注意到您没有处理EOF,并且将getchar()
的结果分配给char
;你不应该因为它返回int
(请参阅'fgetc()
checking EOF'以及其他许多问题,以便对此问题进行另一次讨论)。您还需要确保您的字符串为空终止。您还应该避免重复常量,因此不要在条件中使用80,而是使用LINE_LEN(或者更好的是,sizeof(input_string)-1
)。而且你必须注意一个一个缓冲区溢出。所以,我func1()
的可编辑版本是:
#include <stdio.h>
#include <stdlib.h>
#define LINE_LEN 80
extern char *func1(void);
char *func1(void)
{
int cur_char;
char *input_ptr;
int chars_read = 0;
char input_string[LINE_LEN+1];
while ((cur_char = getchar()) != EOF && cur_char != '\n' && chars_read < LINE_LEN)
input_string[chars_read++] = cur_char;
input_string[chars_read] = '\0';
input_ptr = &input_string[0]; /* set pointer to address of 0th index */
return input_ptr;
}
这仍然是破坏的代码,因为它返回本地指针。