【发布时间】:2019-01-31 06:21:47
【问题描述】:
我有个任务要写函数:
int read_palindrome(); // input comes from stdin
将从标准输入中读取一行,如果该行是回文则返回 1,否则返回 0。一行由换行符 ('\n') 终止,并且不包括换行符。
需要满足的条件:
没有关于输入长度的假设。 您也不允许两次读取输入,例如读取输入,忘记读取输入但记住长度,再次读取输入。这导致输入被读取两次。
您也不能创建一个非常大的缓冲区来存储输入推理,即输入行可能会小于一个非常大的缓冲区。 这个限制的原因是我们会考虑程序的内存使用情况。
任务是提出具有最佳 CPU 时间和内存使用率的正确程序。
以下是我的尝试。
file1.c
#include <stdio.h>
extern int read_palindrome();
int main()
{
if (read_palindrome()) printf("input is a palindrome");
else printf("input is not a palindrome");
return 0;
}
file2.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int check_palindrome2(char *, int);
int read_palindrome() {
unsigned int len_max = 128;
unsigned int current_size = 0;
char *pStr = malloc(len_max);
current_size = len_max;
int i = 0;
char c;
if (pStr != NULL) {
while (( c = getchar() ) != '\n') {
pStr[i] = (char)c;
i++;
if(i == current_size) {
current_size += len_max;
char *tmp = realloc(pStr, current_size);
if (tmp == NULL) {
free(pStr);
return 2;
}
pStr = tmp;
}
}
pStr[i] = '\0';
free(pStr);
}
return check_palindrome2(pStr,i);
}
int check_palindrome2(char *s, int length) {
for (int i = 0; i < length; i++) {
if (s[i]!= s[length-i-1]) {
return 0;
}
}
return 1;
}
将文件复制到两台机器上后,在我的 MacOS 和 Ubuntu 上运行适当的编译命令,并输入已知的回文 121。
gcc -c file1.c
gcc -c file2.c
gcc -o output file1.c file2.c
./output
代码在 MacOS 上打印 input is a palindrome,但在 Ubuntu 上打印 input is not a palindrome。谁能告诉我我的代码是否有任何问题,或者我应该在不同的操作系统上做一些不同的事情。
【问题讨论】:
-
您的程序释放
pStr,然后继续访问它。这是未定义的行为。使用valgrind或地址清理程序来捕获此类错误。 -
抱歉,您指的是哪个特定的免费(pStr)?
-
其中有两个。两者都看是不是太复杂了?
-
删除
free将解决该特定错误,但会导致内存泄漏。您只需要在最后一次取消引用指针后释放即可。 -
OT:在调用
malloc()和调用realloc()之后立即检查NULL,如果为NULL,则调用perror( "your error message" );,这将输出您的错误消息以及系统认为发生错误的文字原因stderr
标签: c linux macos memory-management