Im having this weird runtime error whenever I attempt to copy a specific member of an array block.

I get this from the output:

ASSERT failure in QHash: "Iterating beyond end()", file tools/qhash.cpp, line 293
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.

I redid the code so i could specify what seems to be causing the problem.

    //"Heading" is a QString

     someClass *pointerFromArrayBlock = &theArray[10];

      cout<< pointerFromArrayBlock->Heading() <<endl;//runs fine

      QString test = pointerFromArrayBlock->Heading();//causes crash


     someClass *pointer_NOT_FromArray = new someClass(/*some parameters*/);

          cout<< value_NOT_FromArray->Heading() <<endl;//runs fine

          QString test2 = value_NOT_FromArray->Heading(); //runs fine

Not enough information. The only thing that might be a problem in the code you posted is &theArray[10] potentially being an out of bounds index.

The array has 96 items, I was able to call cout on a string member funtion from that block, but it crashes when I try to copy and assign that same string member funtion's return to a varible

Edited 4 Years Ago by James19142

You say Heading is a QString. Why to you have the () after it? Is it a function that returns a QString? What happens if you do QString = theArray[10].Heading()?

I didnt actually figure what the problem was but it had something to do with using memcpy to create the array as a clone of another, I replaced memcpy with a simple for loop and it ran with no problems, although if anyone has an idea what the problem was, I'd still like to know before marking this problem as solved

this is what I did before:

 memcpy(&DefaultComponentHolder, &tmp, sizeof(tmp));

I never used memcpy before so I might've been using it incorrectly

this worked without any problems:

for(int c = 0; c < DefaultComponents_Arraysize; c++)

   DefaultComponentHolder[c] = tmp[c];

@NathanOliver Heading is a QString function.

QString = theArray[10].Heading() //would cause the runtime error 

cout<< theArray[10].Heading().toStdString();//runs fine which confuses me

// it only would crash when i copy Heading()'s return

Edited 4 Years Ago by James19142

I think that you need to use memcpy like this:

memcpy( &DefaultComponentHolder, &tmp, DefaultComponents_Arraysize*sizeof( tmp ) );

memcpy needs to know the total amount of memory that it is going to copy. That is, the number of things multiplied by the size of each thing.

The mysterious behaviour that you see could be due to the fact that the assignment operator causes a deep copy of the QString, whereas the stream extraction operation does not. You're using the index 10 in the example here, is that a random index? (i.e. does the same problem occur with index 11 or 23 as well?) If the value of 10 is the result of looping over all the indices and you noticed that it is failing on 10, then it could be due to the bad memcpy. The way that you have the memcpy, it will only be copying a single element of the array. When it tries to do a deep copy on assignment, it will find that there's some garbage where the QString should be. This will mean that it's most likely missing some vital string-terminating structure and it's just running on in memory. When you say that the std::cout statement "runs fine" does the output make sense? Is it printing what you would expect or just gibberish?

That's all wild speculation though, so don't be suprised if it's something totally different :)

Finally, you might want to consider using std::copy as an alternative to memcpy, the syntax is nicer, there's some kind of type-safety in there and I don't think that there's any real efficiency difference between them. std::copy can actually be faster in some circumstance, I think:

std::copy( &DefaultComponentHolder, &DefaultComponentHolder + DefaultComponents_Arraysize, &tmp );

Finally, you might want to consider using std::copy as an alternative to memcpy, the syntax is nicer, there's some kind of type-safety in there and I don't think that there's any real efficiency difference between them. std::copy can actually be faster in some circumstance

I'd be shocked if std::copy() were more efficient when copying non-POD types because it guarantees that constructors are called and all the nifty stuff that makes C++ work happens. For built in and POD types the compiler will likely optimize to the point of being competitive with memcpy() if not equal to memcpy(), but I have trouble believing that it could ever be faster. memcpy() just blindly copies bytes, usually in the most efficient way possible for the platform. The definition of std::copy() isn't conducive for the optimizations that memcpy() is capable of.

What's really terrifying is that memcpy() on non-POD types:

  1. Doesn't call constructors.
  2. Doesn't respect the structure of class hierarchies.
  3. Is technically undefined behavior.

Therefore, use of memcpy() is considered a bug for all but built in and POD types. So you kind of ended up at the same suggestion I'd make, but for different reasons. ;)

Edited 4 Years Ago by deceptikon

After reading these responses i think i would've encountered a second problem by using memcpy() incorrectly resulting in empty array blocks, and the weird issues with the blocks copied were caused by the recklessness of memcpy(). So guess i should use it only with simple data types, for complex types std::copy(). I appreciate all the help.

Edited 4 Years Ago by James19142

This question has already been answered. Start a new discussion instead.