c - 在c中使用指针覆盖内存的可能性?

标签 c pointers overwrite

我已经按照 K&R c 书编写了自己的 getline 函数

void getline(char * const str) 
{
  int c;
  char* temp = str;
  while ((c=getchar()) != '\n') {
    *temp = c;
    temp++;
  }
  *temp = '\0'
}

用于初始化字符串

char *str1, *str2;
printf("Type string 1: ");  
getline(str1);
printf("Type string 2: ");  
getline(str2);

只是奇怪,如果str1str1指向的内存位置非常接近,那么getline(str2)会覆盖其中的内容字符串 1?

那是可能的,我怎么能避免呢?谢谢!

更新:

是的,程序停止执行上面的代码片段,但下面的代码有效:

#include <stdio.h>
main()
{
  char* str;
  char* temp = str; 
  int c;
  while ((c=getchar()) != '\n') {
    *temp = c;
    ++temp;
  }
  *temp = '\0';
  printf("%s\n", str);
}

这里的str也是未初始化的字符指针,但为什么不报错呢?

最佳答案

您拥有的是 Undefined Behavior .

说明:

您声明了两个指向 char 的指针:

char *str1, *str2;

但是你还没有初始化它们。它们指向一些“随机”内存位置,因为它们未初始化。

然后,将 str1str2 传递给 getline 并在此处:

char* temp = str;

temp 指向 str 指向的位置。然后,在循环中,

*temp = c;

您写入此内存位置。这将写入无效的内存位置。并调用 UB .

修复:

  1. 您可以使用固定大小的自动数组:

    char str1[101], str2[101];
    

    请注意,您应该在 getline 函数的循环中添加一个检查,当用户输入 100 个字符时,它会中断循环,这样就不会出现 buffer overflow 了。 .

  2. 更好的解决方案是使用动态内存分配。为此,您需要使用 mallocrealloc。这些函数需要 stdlib.h header 。

    固定代码 (未测试):

    char* getline() 
    {
      char* str;
      int c, size = 10, counter = 0;
    
      str = malloc(size); /* Allocate `size` memory */
    
      if(str == NULL)
      {
        printf("malloc failed to allocate memory");
        exit(-1); /* Exit the program */
        /* Or
        return NULL;
        */
      }
    
      while ((c = getchar()) != '\n' && c != EOF) { /* Added check for EOF as well */
        str[counter] = c;
        counter++;
    
        if(counter == size)
        {
          char* temp = str; /* Backup in case realloc fails */
          size += 10; /* Which is the same as `size = size + 10` */
          str = realloc(str, size); /* realloc size(20) memory */
    
          if(str == NULL) /* If realloc failed */
          {
            printf("reallocing memory failed");
            str = temp; /* str is NULL, retrieve the original contents */
            break; /* Break out of the loop */
          }
        }
      }
    
      str = realloc(str, counter + 1); /* realloc `counter + 1` memory */
    
      str[counter] = '\0';
      return str;
    }
    

    在调用函数中,

    char* str1 = getline();
    if(str1)
      puts(str1);
    free(str1);
    
    
    char* str2 = getline();
    if(str2)
      puts(str2);
    free(str2);
    

关于c - 在c中使用指针覆盖内存的可能性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32806177/

相关文章:

python - 如何将 PyObject* 指针设置为 None?

python - 使用makedirs创建文件夹时如何覆盖已存在的文件夹?

spring - 如何按名称覆盖 Spring 服务 bean,仅使用注释

c - 如何不使用++ 运算符直接移动到指针位置?

c - 使用 sscanf 从文件读取时变量覆盖其他变量

c - malloc 和 realloc 函数

在proteus上为atmega 1281配置外部时钟

c - 在 C 中,当我在函数签名之后、函数体之前声明一个变量时,这意味着什么?

无法在 C 中正确使用 strstr()

c++ - 我在阵列中的什么位置?