简体   繁体   English

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

[英]possibility of memory overwrite using pointers in c?

I've written my own getline function following K&R c book 我在K&R c书之后写了自己的getline函数

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

and it's used to initialize strings 它用于初始化字符串

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

Just wonder that, what if the memory locations str1 and str1 point to are very close, then getline(str2) overwrites contents in string 1? 只是想知道,如果存储位置str1str1指向的位置非常接近,那么getline(str2)覆盖字符串1中的内容怎么办?

It that's possible how could I avoid it? 有可能我怎么避免呢? THANKS! 谢谢!

Update: 更新:

Yes the program stops executing the above code snippet but the code below works: 是的,程序停止执行上述代码片段,但以下代码有效:

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

Here the str is also uninitialized character pointer but why deoesn't it give me an error? 这里的str也是未初始化的字符指针,但是为什么它不会给我一个错误?

What you have is Undefined Behavior . 您拥有的是未定义行为

Explanation: 说明:

You declared two pointers to char : 您声明了两个指向char指针:

char *str1, *str2;

but you haven't initialized them. 但您尚未初始化它们。 They point to some "random" memory location as they are uninitialized. 它们指向未初始化的某个“随机”存储位置。

Then, you pass str1 and str2 to getline and here: 然后,将str1str2传递到getline以及此处:

char* temp = str;

temp points to where str points to. temp指向str指向的位置。 Then, in the loop, 然后,在循环中

*temp = c;

you write to this memory location. 您写入此存储位置。 This writes into an invalid memory location. 这将写入无效的内存位置。 And invokes UB . 并调用UB

Fix: 固定:

  1. You can use an automatic array with a fixed size: 您可以使用固定大小的自动数组:

     char str1[101], str2[101]; 

    Note that you should add a check in the loop in the getline function which breaks the loop when the user has entered 100 characters so that there won't be a buffer overflow . 请注意,您应该在getline函数的循环中添加一个检查,当用户输入100个字符时,该循环会中断循环,以免缓冲区溢出

  2. A better solution would be to use dynamic memory allocation. 更好的解决方案是使用动态内存分配。 You need to use malloc and realloc for that. 您需要为此使用mallocrealloc These functions require the stdlib.h header. 这些功能需要stdlib.h标头。

    Fixed code (untested) : 固定代码 (未经测试)

     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; } 

    and in the calling function, 在调用函数中

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

str1 and str2 are not initialized thus it'll be undefined behaviour. str1str2未初始化,因此将是未定义的行为。 You can access to not allowed memory which will crash your program. 您可以访问不允许的内存,这将使您的程序崩溃。

You have to allocate enough memory for each pointer and pass its size to get line function to ensure you write only in allocated memory. 您必须为每个指针分配足够的内存,并传递其大小以获取行函数,以确保仅在分配的内存中写入。

str1 and str2 are uninitialized.Right now you write ( *temp = c; ) at invalid (or unauthorized) memory location invoking UB . str1str2初始化。现在,您在调用UB的无效(或未授权)存储位置写入( *temp = c; )。

First you need to allocate memory to str1 and str2 . 首先,您需要为str1str2分配内存。

str1=malloc(100);     // check return 
str2=malloc(100);

To be able to write into that memory location. 为了能够写入该内存位置。

Just wonder that, what if the memory locations str1 and str1 point to are very close, then getline(str2) overwrites contents in string 1?It that's possible how could I avoid it? 只是想知道,如果内存位置str1和str1指向的位置非常接近,那么getline(str2)会覆盖字符串1中的内容,那怎么可能呢?

And as far as you concern , memory allocated by these malloc won't overlap (will be two different contagious memory blocks) , so if you also tend to write beyond these memory location ,you will invoke undefined behaviour ( if you are lucky segmentation fault ) . 而且就您而言,由这些malloc分配的malloc不会重叠(将是两个不同的可感染内存块),因此,如果您还倾向于写超出这些内存位置的内容,则会调用未定义的行为如果您遇到了幸运的分段错误) )。 So, IMHO, there won't be any case of str2 over-writing str1 . 因此,恕我直言,不会发生str2覆盖str1任何情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM