Hey everyone,

I'm relatively new to C++, cant seem to find a solution to my problem.

I'm trying to randomly generate an array of class objects. I'm using rand() to generate a number 1-3, for the number of objects to generate.

For some reason when I use:

int c_gen = rand()%3+1;	
ob ob1[c_gen];

I get a compile error:
error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'ob1' : unknown size

But, if I use any given number such as 3:
ob ob1[3];
The program compiles fine.

I'm not sure what the problem, I even output c_gen just to see if it was generating a number, and it is.

Recommended Answers

All 13 Replies

That's because you can not set the size of an array at runtime. If you want do this, research dynamic allocations using the new keyword.

Ah ok that makes sense, didn't think about that. Thanks.

I got it working by using:

int c_gen = rand()%3+1;
OB *ob1;
ob1 = new OB[c_gen];

Thanks again!

I got it working by using:

int c_gen = rand()%3+1;
OB *ob1;
ob1 = new OB[c_gen];

Thanks again!

Okay, but now you have to be cautious of memory leaks, when you have finished doing stuff with ob1, you MUST free that memory using the delete oeprator, like this:

delete[] ob1;

Hope this helps.

Okay, but now you have to be cautious of memory leaks, when you have finished doing stuff with ob1, you MUST free that memory using the delete oeprator, like this:

delete[] ob1;

Hope this helps.

Just read about delete[], good learning experience.

Thanks again.

Alright, now I have a new problem.

How would I remove a single element from the object array? I've tried a few things and looked it up, but I cant seem to get it.

Lets say:

OBJECT ob1[3];  //class OBJECT

And I want to remove the 3rd element of ob1[];

Alright, now I have a new problem.

How would I remove a single element from the object array? I've tried a few things and looked it up, but I cant seem to get it.

Lets say:

OBJECT ob1[3];  //class OBJECT

And I want to remove the 3rd element of ob1[];

See posts 28 and 29 in this thread for a discussion on how to delete elements from an array. There are some potential pitfalls.

http://www.daniweb.com/forums/thread195873-3.html

Too many problems on a single (and simple) program case is a symptom of bad design solution.

Evidently in that case you need different data structure. You want dynamically defined data structure size - but an array size in C++ is a compile-time defined (constant) expression. You want to remove selected elements - but an array never changes its size after allocation.

Better think about STL vector container.

std::vector<Object> v(rand()%3+1);
cout << v.size() << " elements\n";
...
v.erase(v.end()-1);  // remove last
...
v.erase(v.begin()+i);// remove i-th
...
Object obj;
v.push_back(obj); // append new obj

I don't see much need in actually deleting the one element by itself. If you don't need that element, simply ignore it until it's time to completely destruct the array.

If you want to remove an item in the middle of the array, it's easiest to use ArkM's suggestion and use STL containers, but it's a simple task either way. Simply shift each element after the deleted index left by one place, like this:

#include <iostream>
using namespace std;

void removeElement(int nums[], int size, int index) {
  memmove(
    &nums[index],                  // Dest
    &nums[index + 1],              // Source
    (size - index) * sizeof(int)   // Size
  );
}

int main() {
  int nums[5] = {1,2,3,4,5};
  int numCount = 5;
  int removeIndex = 2;

  removeElement( nums, numCount, removeIndex );
  --numCount; // Shorten array length

  for (int i = 0; i < numCount; ++i)
    cout << nums[i];
}

This outputs:

1245

William, we don't know base element type. If it's a class object (see OP), memmove can't move elements correctly! Moreover, remove class object means call destructor...

>If it's a class object (see OP), memmove can't move elements correctly!
What do you mean? All memmove does is move memory. So even if you want to use your own class object, it should still work.

#include <iostream>
using namespace std;

struct mystruct {
  char text[5];
};

template<typename type>
void removeElement(type a[], int size, int index) {
  memmove(
    &a[index],                      // Dest
    &a[index + 1],                  // Source
    (size - index) * sizeof(type)   // Size
  );
}

int main() {
  mystruct a[5] = {"a","b","c","d","e"};
  int elementCount = 5;
  int removeIndex = 2;

  removeElement( a, elementCount, removeIndex );
  --elementCount; // Short array length

  for (int i = 0; i < elementCount; ++i)
    cout << a[i].text;
}

>remove class object means call destructor...
I know, but that's why I asked if there was any real need to destruct the element, when you can just you can simply ignore it and shift array elements around without the need of having to free any memory until the very last moment.

Though as you said, I agree that the OP should stick to SDL containers for the reasons you have suggested.

>What do you mean? All memmove does is move memory. So even if you want to use your own class object, it should still work.
It's so simple. Suppose the object has a member which is a head of double linked list (why not?). Now move it by memmove and think about the back pointer of the 1st node and the next pointer of the last one (both refer to the list head). That's why we overload assignment operator for complex classes. I'm sure that you can invent other (simple) examples of such classes.

Moral of a story: use memmove for POD variables only, never use it for class objects.

Too many problems on a single (and simple) program case is a symptom of bad design solution.

Evidently in that case you need different data structure. You want dynamically defined data structure size - but an array size in C++ is a compile-time defined (constant) expression. You want to remove selected elements - but an array never changes its size after allocation.

Better think about STL vector container.

std::vector<Object> v(rand()%3+1);
cout << v.size() << " elements\n";
...
v.erase(v.end()-1);  // remove last
...
v.erase(v.begin()+i);// remove i-th
...
Object obj;
v.push_back(obj); // append new obj

That makes it a lot easier to manage the objects being created. I'll be honest and say that this is for a simple (go figure) RPG game that I'm making to further understand C++ concepts. I thought using an object array would be perfect for generating a number of enemies during an encounter. I didn't think to use the STL Vector. Thanks for the insight.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.