strtol有什么问题?

use*_*916 -1 c

我有这个代码,它应该运行正常,但由于某种原因,循环将循环通过我在循环的条件检查之前释放字符串.从循环中退出的唯一方法是给出超过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在做什么.

n. *_* m. 8

free(error);
Run Code Online (Sandbox Code Playgroud)

去掉它.error未分配在strtol其他任何地方.它是一个指向中间的指针string.释放它是UB.


Mic*_*urr 5

你说:

由于某种原因,当我在循环的条件检查之前释放字符串时,循环将循环遍历

请记住,通过调用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它将指向已释放的内存。