0

So I decided to write my own Big Integer library for a microcontoller in C (the PIC32 if that matters), but I'm having a weird problem that I don't understand. When the code is run, the big_int_t structs a and b are at different memory locations, but a->bytes and b->bytes appear to be at the same location (confirmed by printing their pointers). Setting a value in b->bytes also changes the value in a->bytes. In the main function below, printing the first element from either struct's bytes array shows 41. Am I doing something wrong?

#include <stdint.h>
#include <stdio.h>

typedef struct {
  uint8_t size;
  uint8_t *bytes;
} big_int_t;

void big_init(big_int_t *big, uint8_t size) {
  big->size = size;
  uint8_t bytes[size];
  big->bytes = bytes;
  uint8_t i;
  for(i=0;i<big->size;i++) big->bytes[i] = 0;
}

int main() {
  big_int_t a,b;
  big_init(&a,1);
  big_init(&b,1);
  a.bytes[0] = 16;
  b.bytes[0] = 41;
  printf("%d\n",a.bytes[0]);
  printf("%d\n",b.bytes[0]);
}
1
  • Use malloc to get memory for bytes. Do not use stack variable. Commented Apr 3, 2015 at 10:55

3 Answers 3

2

In big_init the variable bytes is a local Variable, one that will go out of scope and disappear once the function returns. The pointer stored in big->bytes will become a stray pointer when the function returns, and dereferencing the pointer will lead to undefined behavior.

You can't use a local array for this, instead you need to allocate the array dynamically with malloc:

big->bytes = malloc(sizeof(*big->bytes) * big->size);

But don't forget to free the memory once you're done with it.

Sign up to request clarification or add additional context in comments.

Comments

0

You are allocating your byte buffer on the stack:

uint8_t bytes[size];

When big_init exits the buffer is no longer valid. It will get randomly overwritten.

You probably want to dynamically allocate it using malloc(), but then you have to be careful to free it up again.

Comments

0

The reason for this behaviour is that you are assigning bytes with a pointer on the stack. When calling big_init for the first time, the local variable bytes will be placed on the stack and it's address will be used for bytes in the struct. Afterwards, you are calling the function big_init again. Now, the same stack as before is build up, and the local variable bytes is placed on the same location as before. Therefore, the two assignments lead to the same pointer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.