0

I'm still a beginner, so I don't know much and I'm sorry if it looks too dumb. I was learning about memory leak and how to use malloc(), calloc(), free() and realloc().

I tried this sample above on visual studio, however when I saw the results after using realloc, I didn't got the same values that was before on that struct.

#include <iostream>
#include <string>


struct sNum
{
    int b = 0;
};

int main()
{
    int n = 10;
    struct sNum* a;
    a =(struct sNum*) malloc(n * sizeof(struct sNum));
    for (int i = 0; i < n; i++)
    {
        a[i].b = i;
        std::cout << std::to_string(a[i].b) + " ";
    }
    std::cout << "\n";
    n++;
    a = (struct sNum*)realloc(a, n);
    a[n - 1].b = n - 1;
    for (int i = 0; i < n; i++)
    {
        std::cout << std::to_string(a[i].b) + " ";
    }   
    return 0;
}

Running that code on visual studio, it results:

0 1 2 3 4 5 6 7 8 9
0 1 -50331646 -570556931 -572662307 -572662307 -757975909 -2147479587 -572662307 -572662307 10

I was expecting the same sequence, plus 10 at the end. Anyone knows what I'm doing wrong? Thx in advance!

  • 8
    Don't use those in C++ unless you have a really good reason to. – ChrisMM Dec 21 '22 at 00:39
  • 2
    your second parameter of realloc is the wrong size "units". it should be n*sizeof(sNum). What's happening is the libc is making your allocation smaller, and then putting some debugging fence after the end of it so it can detect when you've overflowed the allocated memory. that's what's stomping on yoru previous data – Russ Schultz Dec 21 '22 at 00:41
  • 2
    Side note: In contrast to C, in C++, it is sufficient to write `sizeof(sNum)` instead of `sizeof(struct sNum)`. – Andreas Wenzel Dec 21 '22 at 00:50
  • 6
    "*I'm still a beginner*" and "*I was learning about memory leak and how to use malloc(), calloc(), free() and realloc()*" Should not go in the same paragraph. Beginner C programmers need to know about those, but beginner C++ programmers should not. It sounds like you're learning from bad sources. – Nicol Bolas Dec 21 '22 at 00:50
  • Side note: Instead of `std::cout << std::to_string(a[i].b) + " ";`, you can simply write `std::cout << a[i].b << " ";`. Using `std::to_string` is only necessary with the `char` data type, in order to force it to be interpreted as a number to be printed, instead of a character code whose character should be printed. (Note that this comment is a repost of a previous comment which contained an error, which I have now fixed). – Andreas Wenzel Dec 21 '22 at 01:07
  • @NicolBolas Hi! Do you mind to explain why I shouldn't care about memory leak on C++ or what should I do instead of those functions? Also if you could share a recommended source (book, site, or whatever), it would be wonderful. – Victor Rocon Covre Dec 21 '22 at 01:22
  • In c++ you should not use new: [https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new](https://stackoverflow.com/questions/6500313/why-should-c-programmers-minimize-use-of-new) – drescherjm Dec 21 '22 at 01:51
  • 3
    @VictorRoconCovre: What others are pointing out is that C++ memory management is a lot easier and less error-prone than C-style memory management (`malloc` and `realloc`). If you use [`std::vector`](https://en.cppreference.com/w/cpp/container/vector/vector) instead, then your program would look like [this](https://godbolt.org/z/K1YGnhfbj). – Andreas Wenzel Dec 21 '22 at 01:53
  • Most of your code looks like it is written in "C" who is teaching you C++? – Pepijn Kramer Dec 21 '22 at 04:02
  • @AndreasWenzel thx again! So I should be using vectors instead of solving the problem with pointers? I see. – Victor Rocon Covre Dec 21 '22 at 09:15
  • @VictorRoconCovre: Oh, I just noticed that I provided the incorrect link for `std::vector` in my previous comment. By mistake, I linked to the constructor, instead of to the class. [Here](https://en.cppreference.com/w/cpp/container/vector) is the correct link. – Andreas Wenzel Dec 21 '22 at 10:30

1 Answers1

4

Assuming that sizeof(sNum) is 4 on your platform, the line

a =(struct sNum*) malloc(n * sizeof(struct sNum));

will allocate 40 bytes of memory.

The line

a = (struct sNum*)realloc(a, n);

will shrink the allocated memory to 11 bytes, which is only sufficient to store 2 elements.

Due to this, the line

a[n - 1].b = n - 1;

will invoke undefined behavior, because valid indexes into a are only 0 and 1 (because there is only room for 2 elements), however you are using the index 10.

Therefore, to fix this, you should change the line

a = (struct sNum*)realloc(a, n);

to:

a = (struct sNum*)realloc( a, n * sizeof(sNum) );
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39