-1

I have a weird problem with dynamic memory allocation. Whenever I dynamically allocate a member of a structure with only one int I can write us many I wanted instead of only one int like a normal variable not an array. This is my code with some commentary and maybe you can tell what I'm doing wrong or what point I skipped:

#include <stdio.h>
#include <stdlib.h>

typedef struct{
    int *sign_h;
    int max_chars;
} myformat;

int main()
{
    myformat *myfile=malloc(sizeof(myformat)); // one struct
    myfile->max_chars=100;
    myfile->sign_h=malloc(1*sizeof(int)); //size of one int
    myfile->sign_h[333]=50; //Is this suppose to work?
    printf("test %d",myfile->sign_h[333]); // printf print value of 50 
    FILE* f1=NULL;
    char nume[]="myfile.bin";
    f1=fopen(nume,"wb");
    fwrite(&myfile,sizeof(myformat),1,f1);
    fclose(f1);
    return 0;
}

PS: And what about C++? if I make it in C++ I get different results?

eddie
  • 1,252
  • 3
  • 15
  • 20
user3134909
  • 141
  • 2
  • 7
  • 5
    congratulations, you've discovered buffer overflow – Iłya Bursov Apr 14 '16 at 20:28
  • Undefined behavior is undefined. – EOF Apr 14 '16 at 20:30
  • 2
    The language doesn't stop you from shooting yourself in the foot, so it's your responsibility to avoid doing that. – jamesdlin Apr 14 '16 at 20:30
  • Maybe some reading on [pointer arithmetic](https://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html) would be valuable. – Alyssa Haroldsen Apr 14 '16 at 20:30
  • `myfile->sign_h[333] = 50` assumes that the buffer pointed to by `sign_h` has at least 334 integers of space (since an array starts at index 0, so the first integer is `sign_h[0]`, the second `sign_h[1]`, etc). Your allocation `malloc(1*sizeof(int))` allocates exactly *one* integer of space. I think you can figure out the rest. :) – lurker Apr 14 '16 at 20:32
  • OP: for further reference: http://stackoverflow.com/q/33047452/472647 – CodeMouse92 Apr 14 '16 at 20:51
  • 1
    C and C++ are in close agreement on what happens here: Undefined. – user4581301 Apr 14 '16 at 20:56

1 Answers1

3

C doesn't care if you write off the end of an array, it just follows orders. When you call

    myfile->sign_h[333]=50; //Is this suppose to work?

What you're really doing is saying, "Write 50 to the 4 bytes that are 333 * sizeof(int) bytes after the location of sign_h in memory. C says, "OK, done", regardless of the consequences.

Speaking of consequences, there could be many negative ones from doing that, including:

  1. If you make another call to malloc, it might give you back a block of memory that contains where you just wrote to memory. If so, you might clobber the value you just wrote. If you previously made a call to malloc this could happen as well.
  2. You could segfault. Malloc has its own data structures under the hood for maintaining information about blocks of memory it's allocated to the user. By writing to some random, arbitrary space, you could be corrupting malloc's data structures.

Basically, don't use memory you haven't asked for.

Byte Lab
  • 1,576
  • 2
  • 17
  • 42