我有这个代码,它应该运行正常,但由于某种原因,循环将循环通过我在循环的条件检查之前释放字符串.从循环中退出的唯一方法是给出超过3位的整数(输入> 99 || input <-99).我正在使用gcc编译此代码,代码:: blocks作为IDE.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* createString(void);
int main() {
int temp = 0;
char* string = 0;
char* error = 0;
do {
printf("\n Integer: ");
string = createString();
temp = strtol(string, &error, 10);
if (*error != '\n' && *error != '\0') printf("\n Input is not an integer");
free(string);
string = 0;
} while (*error != '\n' && *error != '\0');
free(error);
error = 0;
return 0;
}
char* createString() {
char* string = 0;
size_t size = 0;
size_t index = 0;
int ch = EOF;
do {
ch = getc(stdin);
if (ch == EOF || ch == '\n') ch = 0;
if (size <= index) string = (char*) realloc(string, size += 5);
if (!string) {
perror("realloc");
exit(EXIT_FAILURE);
}
string[index++] = ch;
} while(ch);
return string;
}
Run Code Online (Sandbox Code Playgroud)
我通过将自由进程移动到循环周期的开始和循环之后来解决它.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* createString(void);
int main() {
int temp = 0;
char* string = 0;
char* error = 0;
do {
free(string);
string = 0;
printf("\n Integer: ");
string = createString();
temp = strtol(string, &error, 10);
if (*error != '\n' && *error != '\0') printf("\n Input is not an integer");
} while (*error != '\n' && *error != '\0');
free(string);
string = 0;
free(error);
error = 0;
return 0;
}
char* createString() {
char* string = 0;
size_t size = 0;
size_t index = 0;
int ch = EOF;
do {
ch = getc(stdin);
if (ch == EOF || ch == '\n') ch = 0;
if (size <= index) string = (char*) realloc(string, size += 5);
if (!string) {
perror("realloc");
exit(EXIT_FAILURE);
}
string[index++] = ch;
} while(ch);
return string;
}
Run Code Online (Sandbox Code Playgroud)
代码现在工作正常,但我想知道strtol在做什么.
free(error);
Run Code Online (Sandbox Code Playgroud)
去掉它.error未分配在strtol其他任何地方.它是一个指向中间的指针string.释放它是UB.
你说:
由于某种原因,当我在循环的条件检查之前释放字符串时,循环将循环遍历
请记住,通过调用strtol(string, &error, 10);,指针error将指向字符串string。因此,如果您string在执行此操作之前有空:
if (*error != '\n' && *error != '\0') printf("\n Input is not an integer");
Run Code Online (Sandbox Code Playgroud)
或这个:
while (*error != '\n' && *error != '\0')
Run Code Online (Sandbox Code Playgroud)
您将调用未定义的行为,因为error它将指向已释放的内存。