-1

Consider that I have a struct as below. I want to reset this struct.

struct StProduct {
  int weight;
  int price[100];

StProduct():
  weight( 0 ),
  price( ) {}
};

This way to reset the struct is given in a lot of examples and works :

StProduct apple;
// some code ...
apple = StProduct();

Now we'll dynamically allocate. Is it valid to reset the struct like this:

StProduct* pbanana = new StProduct();
// some code ...
*pbanana = StProduct();

Or could it be that there is some undefined behavior involved?

Clarification of the embedded nature of the question:

The question is really only the one above, and can be answered as such.

People seem to be concerned about a Minimal, Complete, and Verifiable example.

Therefore let me add the following explanation:

My x86 unit tests with the code above work. But on an embedded device (STM32 F427) with gcc 4.7.6, an RTOS and having the struct as permanent buffer in the core coupled memory, the line *pbanana = StProduct(); in the code called every 100ms leads to a crash after roughly 30min, while commenting this line out has the device running for 3 days now. This is why I was asking, if the code above might be associated with undefined behaviour. Since it apparently is not, I am thankful for the comments and have to look somewhere else - and my bet is on a compiler bug. If someone has any idea how I can provide a Minimal, Complete, and Verifiable example that does not involve sending hardware to everyone, I'm all ears.

Nikolai
  • 359
  • 2
  • 10
  • Both ways are fine. If you getting memory problems we'll need a [mcve] – NathanOliver Aug 19 '17 at 23:10
  • It is an embedded device with specific toolchain. So I cannot give you a proper example. I wanted to verify here that the dynamic way is not against the standard. Now with your answer, I'm thinking more like a compiler bug. – Nikolai Aug 19 '17 at 23:13
  • The approach you have shown is fine. If there is memory corruption occurring over time, the problem is in other code (e.g. that might include the code you've shown as a part). In the second case, there needs to be a `delete pbanana` eventually to avoid a memory leak (when that object is no longer needed). Beyond that, you need to provide an [mcve] - nobody can help you find a problem in code you haven't provided. – Peter Aug 19 '17 at 23:19
  • To reset the struct, you could use `memset` – lost_in_the_source Aug 19 '17 at 23:39
  • My guess is you're getting memory corruption because you're declaring an object on the stack and blowing the stack.. – Russ Schultz Aug 20 '17 at 00:27
  • I suppose you meant "POD" and not "PDO"? Well, your `StProduct` is **not** a POD. To be a POD, a struct must satisfy the trivial type requirements, which mandates, among other things, that all non-deleted constructors must be trivial. Your constructor is not, as a trivial constructor must not be user-provided. On the bright side, you probably don't need your type to be a POD, but just a [standard-layout type](http://en.cppreference.com/w/cpp/concept/StandardLayoutType). – spectras Aug 20 '17 at 02:06
  • 1
    PDO = Process Data Object, a certain kind of CAN frame used in embedded CANopen systems. POD = Plain Old Data, [informal C++ slang](https://stackoverflow.com/questions/146452/what-are-pod-types-in-c). And this would be why using TLA:s (three letter abbreviations) is a RBI (really bad idea). – Lundin Aug 21 '17 at 12:56
  • @Lundin VWS (very well said). – el.pescado - нет войне Aug 22 '17 at 06:01

1 Answers1

1

Your code doesn't cause memory corruption itself, but there may be some kind of work with uninitialized memory. Your approach works fine if everything is managed properly.

When you call int price[100]; it will allocate 100 ints of memory that price points to, but it doesn't say anything about the contents. If you want to make sure they are, for example, 0 after construction, you can initialize the array in the constructor:

StProduct() : weight(0) {
    for(int i = 0; i < 100; ++ i)
        price[i] = 0;
}

Your current approach does work though, the problem is most likely in another part of the code where it doesn't handle that the memory is uninitialized, unless you assume that the array is 0 initialized.

N00byEdge
  • 1,106
  • 7
  • 18