Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
影响FGET的Realloc_C_Malloc_User Input - Fatal编程技术网

影响FGET的Realloc

影响FGET的Realloc,c,malloc,user-input,C,Malloc,User Input,我正在尝试为用户输入重新创建一个简单的字符串解析器。我可以毫无疑问地获取输入字符串,并确定其中有多少个单独的字符串,以便为malloc提供正确的大小。起初,我在stdin中找不到字符串的数量,只需重新定位我的字符串数组,为多个字符串留出空间,然后malloc新字符串。既然我已经有了尺寸,我相信这是没有必要的,因为我可以为malloc提供合适的尺寸 尝试使用calloc,但在同一位置出现故障 我感到困惑的是,当我在代码中离开realloc时,除了知道它可能会以不希望的方式调整我的数组之外,没有任何

我正在尝试为用户输入重新创建一个简单的字符串解析器。我可以毫无疑问地获取输入字符串,并确定其中有多少个单独的字符串,以便为malloc提供正确的大小。起初,我在stdin中找不到字符串的数量,只需重新定位我的字符串数组,为多个字符串留出空间,然后malloc新字符串。既然我已经有了尺寸,我相信这是没有必要的,因为我可以为malloc提供合适的尺寸

尝试使用calloc,但在同一位置出现故障

我感到困惑的是,当我在代码中离开realloc时,除了知道它可能会以不希望的方式调整我的数组之外,没有任何问题。但是,如果我删除realloc,我的代码会在fgets尝试执行时出错

这正是我调用解析器和include的地方。h保存所有原型和stdlib/bool/io、string/unistd/limits.h

#include "appserver.h"

int main(int argc, char *argv[])
{
  if(argc != 4)
  {
    exit(0);
  }
  struct userInput user = { parseInt(*argv[1]), parseInt(*argv[2]), argv[3] };

  printf("> ");
  char **newArgs = stringParser();
  for (int i = 0; newArgs[i] != NULL; i++)
  {
    free(newArgs[i]);
  }
  free(newArgs);
}
下面是我的解析器代码。如果我不注释realloc,我可以在gdb中单步执行代码,而不会出现问题。使用stdin中的整个字符串显示输入,但是,如果我将其注释掉,我会在尝试在fgets中检索用户输入时正确地选择segfult。为什么评论realloc甚至会对fgets产生影响

char **stringParser()
{
  char *input;
  fgets(input, INT_MAX, stdin);
  int size = numberOfStrings(input);
  char **inputArray = malloc((size)*(sizeof(char*)));
  inputArray[0] = malloc(sizeof(char*));
  strcpy(inputArray[0], strtok(input, " "));
  for(int i = 1; i < size /*inputArray[i-1] != NULL*/; i++)
  {
    // inputArray = realloc(inputArray, (i+1)*sizeof(char*));
    inputArray[i] = malloc(sizeof(char*));
    strcpy(inputArray[i], strtok(NULL, " "));
    printf("Inside inputArray[%d]: %s\n", i-1, inputArray[i-1]); 
  }
  return inputArray;
}
编辑: 我想跟进以确保我已经避免了大多数潜在的未定义行为。 我没有在main中更改任何内容,所以这里是我在**stringParser中的更改

主要的变化领域包括:

我使用calloc而不是malloc,尽管如果我的理解正确,那么callocsize、sizeof*inputArray的行为与忽略“0”或垃圾值初始化时mallocsize*sizeof*inputArray的行为相同 我的一个朋友写了一个*nextLineFILE*输入,允许我通过标准输入法逐个字符地扫描,直到到达EOF或'\n'。这样做的好处是可以精确地分配用户输入所需的内存量。 我确保数组中的每个字符串只分配了必要的内存量。与我以前做的sizeofchar*相反 我已经确保在字符串数组的末尾包含一个null终止值。我在NumberOfString中做了一个更改,我只是在return语句之前添加了count++。 这些改变使我达到了不再有任何内存泄漏的地步。我不敢假设我已经避免了所有未定义的行为,但是,我想我在这一点上做得更好一些。我肯定不会因为一大堆其他问题而阻塞这篇文章,但我想把这个更新留在这里,以防有人发现它有用或相关

realloc的调用不会影响fgets——至少不会直接、可预测或可靠地影响fgets

stringParser中fgetsinput、INT_MAX、stdin的第一个调用具有未定义的行为,因为指针输入未初始化

实际上,fgets的调用可能会覆盖一些不应该覆盖的内存区域

通过添加或注释realloc调用,结果将对程序使用的内存布局进行一些调整,例如更改代码或数据是否位于被FGET覆盖的内存位置

但这并不是因为realloc直接影响FGET。这只是调用realloc会改变程序中某些内容这一事实的副作用

注释掉realloc调用或重新插入它可能会产生任何影响。例如,如果您的代码是使用不同的编译器设置(如优化标志,甚至是不同的编译器)构建的,则可能会得到不同的效果

要消除FGET的问题,请向其传递一个数组

  char input[some_positive_value];
  fgets(input, sizeof(input), stdin);
或者初始化指针以指向合适的缓冲区

  char *input = malloc(some_positive_value);   /*  remember to `free()` when done */
  fgets(input, some_positive_value, stdin);
注意,如上所述,循环确实需要realloc调用

如果没有realloc调用,对inputArray[i]的赋值也将具有未定义的行为。如果你没有看到这种症状,那你就幸运了——再说一次,这是一种你无法依赖的影响


检查各种功能fgets、realloc等是否实际成功也是一个好主意。您的代码是基于这样的假设进行的,即所有函数都按预期工作,但如果它们失败,行为将是未定义的,例如,如果realloc的内存重新分配失败。

请解释char*tempCopy=mallocsizeofchar*行;fgetsinput,INT_MAX,stdin;:输入未初始化。@M.M我只是不喜欢输入原始整数值,还没有实现分配字符串确切长度的方法。或者,如果有任何简单的内置方式来做它,我还没有发现它。出于无知,我刚刚使用了sizeofchar*,因为它还没有给我带来任何麻烦。分配不足的空间,然后在该空间的结尾处写入内容会导致您的问题。正如这个问题所表明的那样,它现在给你带来了麻烦。我想我的困惑是因为如果我只留下realloc,为什么这个问题不会发生?因为FGET发生在realloc甚至m之前 alloc发生了。
  char input[some_positive_value];
  fgets(input, sizeof(input), stdin);
  char *input = malloc(some_positive_value);   /*  remember to `free()` when done */
  fgets(input, some_positive_value, stdin);
 // inputArray = realloc(inputArray, (i+1)*sizeof(char*));
 inputArray[i] = malloc(sizeof(char*));