An Access Violation problem.

I'm learning C++ and I have a problem with dynamic arrays.
What is wrong with the following code?

cout<<"Enter numbers:\n";
int count=0;
double avg=0;
double * numbers = new double [count];
cin>>numbers[count];
while (numbers[count]!=-1)
{
      avg=avg+numbers[count];    //SOMETIMES THE NUMBERS ARRAY DOESN'T PASS IT'S VALUES INTO THE LOOP
      double * temp = new double [count];
      for (int i=0;i<count;i++)
          temp[i]=numbers[i];
      count++;
      numbers=NULL;
      delete [] numbers;
        double * numbers = new double [count];
      for (i=0;i<count;i++)
          numbers[i]=temp[i];
      temp=NULL;
      delete [] temp;
      cin>>numbers[count];   //THIS LINE PRODUCES AN ACCESS VIOLATION.
};
cout<<"\nThe avarage: "<<avg;
cin.get();
return 0;

By the way, I use Visual C++ 6.0.
NightBladerAsked:
Who is Participating?
 
nonubikConnect With a Mentor Commented:
cout<<"Enter numbers:\n";
int count=0;
double avg=0;
double * numbers = malloc(sizeof(double));
cin>>numbers[count];
while (numbers[count]!=-1)
{
     avg=avg+numbers[count];    
     double * temp = new double [count];
     
     count++;
     numbers = realloc(numbers, (count+1)*sizeof(double));
     cin>>numbers[count];
};
cout<<"\nThe avarage: "<<avg;
cin.get();
return 0;
0
 
__Julien__Commented:
The size of your array cannot change after it has been created. Your array here is an array of 0 double. Use a vector instead. Its size can change dynamically.
0
 
nonubikCommented:
NightBlader,
You have to switch two lines between them, like this:

cin>>numbers[count];
double * numbers = new double [count];

Now your 'numbers' vector will be allocated properly.
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
Sys_ProgCommented:
Problems at many places

>>int count=0;
>>double * numbers = new double [count];
>>cin>>numbers[count];

You are allocating an array of 0 length [i.e. no space at all] and then reading a value and storing it into the unavialable space??
You should read some positive count from user, use that count to allocate memory


>>while (numbers[count]!=-1)
What do u mean by this
Where have initialised the array elements to default value of -1


>> double * temp = new double [count];
Memory would be allocated to temp for each iteration. Do u really need this


>>numbers=NULL;
>>     delete [] numbers;
You should first delete & then set it to NULL


>> temp=NULL;
>>     delete [] temp;
Same as above

HTH

Amit







 
0
 
nonubikCommented:
don't mind my commnet, I wad thinking at something totaly else ...
I saw cin>>count.... Obviously I saw wrong
0
 
NightBladerAuthor Commented:
This is the point, I want to make an array which will be a able to change size during runtime.
So I use a dynamic array, when I want to change it's size I delete it and make a new one, putting
the old values in it using a temp array.
Can you please show me how to change the code to solve the problem?
0
 
nonubikCommented:
you can use realloc(..). allocate the array with malloc(..) and in the end deallocate it with free(..);
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_crt_realloc.asp
0
 
nonubikCommented:
and a free(numbers); after the while loop.
and I think you meant cout<<"\nThe average: "<<avg/count;
0
 
oferhCommented:
I think this should do the trick:

cout<<"Enter numbers:\n";
int count=0;
double avg=0;
double * numbers = new double [count+1];
cin>>numbers[count];
while (numbers[count]!=-1)
{
     avg=avg+numbers[count];    //SOMETIMES THE NUMBERS ARRAY DOESN'T PASS IT'S VALUES INTO THE LOOP
     double * temp = new double [count+1];
     for (int i=0;i<count;i++)
         temp[i]=numbers[i];
     count++;
     delete [] numbers;
     numbers=NULL;
     double * numbers = new double [count+1];
     for (i=0;i<count;i++)
         numbers[i]=temp[i];
     delete [] temp;
     temp=NULL;    
     cin>>numbers[count];   //THIS LINE PRODUCES AN ACCESS VIOLATION.
};
cout<<"\nThe avarage: "<<avg;
cin.get();
return 0;
0
 
NightBladerAuthor Commented:
Ah, ok.
But the compiler displays the following:
error C2440: 'initializing' : cannot convert from 'void *' to 'double *'
about this line:
double * numbers = malloc(sizeof(double));

And there is no way to do it with new and delete?
0
 
NightBladerAuthor Commented:
oferh, it doesnt. :/
0
 
rstaveleyCommented:
__Julien__ is right, you ought to use a vector if you want to have an "array" that grows, but if you take a step back from this consider if you really want to store all thos numbers anyhow. Why not simply have:

       double total = 0;
       int count = 0;
       double value;
       while (cin >> value) {
             total += value;
             count++;
       }
       
And then use the total and count to figure out the average. [Exercise left to reader :-) ]  
0
 
nonubikCommented:
my mistake.
double * numbers = (double *)malloc(sizeof(double));
0
 
NightBladerAuthor Commented:
ehem, im not such a newbie to programming rstaveley, I know it does the trick
but I am not making an exercise to find the avarege, I am trying to generally change the size of an array while running the program.
0
 
nonubikCommented:
cout<<"Enter numbers:\n";
int count=0;
double avg=0;
double * numbers = new double [count+1];
cin>>numbers[count];
while (numbers[count]!=-1)
{
     avg=avg+numbers[count];    //SOMETIMES THE NUMBERS ARRAY DOESN'T PASS IT'S VALUES INTO THE LOOP
     double * temp = numbers;
     
     count++;
     double * numbers = new double [count+1];
     for (i=0;i<count;i++)
         numbers[i]=temp[i];
     delete [] temp;
     temp=NULL;    
     cin>>numbers[count];   //THIS LINE PRODUCES AN ACCESS VIOLATION.
};
0
 
NightBladerAuthor Commented:
now the same mistake for:
numbers = realloc(numbers, (count+1)*sizeof(double));
0
 
nonubikCommented:
the same correction
numbers = (double *)realloc(numbers, (count+1)*sizeof(double));
0
 
NightBladerAuthor Commented:
Ah, now it works, Thanks!
0
 
nonubikCommented:
the pleasure was mine..
0
 
rstaveleyCommented:
OK, for what it is worth, here's how to use the standard library vector instead of an array:
--------8<--------
#include <iostream>
#include <vector>

int main()
{
        std::vector<double> valueList;
        double value;
        while (std::cin >> value)
                valueList.push_back(value);

        double total;
        for (int i = 0;i < valueList.size();++i) {
                std::cout << "valueList[" << i << "] is " << valueList[i] << '\n';
                total += valueList[i];
        }
        std::cout << 
                "There are " << valueList.size() << " values\n"
                "Total value is " << total << '\n';
}
--------8<--------

realloc() really belongs in the C TA.
0
 
rstaveleyCommented:
Forgot to initialise the total, but you know I meant to.
0
 
itsmeandnobodyelseCommented:
Here is tested code taking most of your original code:


void main()
{
    cout<<"Enter numbers:\n";
    int count=0;
    double avg=0;
    double * numbers = new double [count+1];
    cin>>numbers[count];
    while (numbers[count]!=-1)
    {
        avg=avg+numbers[count];    //SOMETIMES THE NUMBERS ARRAY
                                                   // DOESN'T PASS IT'S VALUES INTO THE LOOP
        count++;
        double * temp = new double [count+1];
        for (int i=0;i<count;i++)
            temp[i]=numbers[i];
        delete [] numbers;
        numbers = temp;
        cin >> numbers[count];   //THIS LINE PRODUCES AN ACCESS VIOLATION.
    };
    cout<<"\nThe avarage: "<<avg/count << endl;
    cin.get();
    return;
}

The problems have been:

1. double * numbers = new double [count];

It should be count + 1;

2. Redefinition of numbers within the loop

That creates a new variable that isn't identical to 'numbers' out of the scope of the loop.

3. Deleting of numbers that has been set to NULL before

4. Some minor copy loop errors.

Regards, Alex

0
 
NightBladerAuthor Commented:
itsmeandwhatever, thanks, I just didnt understand this:
delete [] numbers;
numbers = temp;
You delete numbers, and without initializing it again give it new values, the computer shouldn't recognize
that numbers...
0
 
nonubikCommented:
numbers = temp
They're pointers, so after that line 'numbers' and 'temp' have the same address. and 'temp' has previously been allocated with new. So 'numbers' points now to the same memory zone as 'temp'.
When delete[] numbers; you just free the memory of 'numbers' (previously allocated).
0
 
itsmeandnobodyelseCommented:
>> delete [] numbers;
>> numbers = temp;

The first statement deletes old pointer to the storage of the numbers array;
The secons statement assigns the pointer temp to the pointer numbers, so now numbers points to the storage that had been allocated with

        double* temp = new double[count + 1];

So, second statement only is an pointer assignment. Therefore, you may not have

       delete [] temp;    // THAT'S WRONG

below as temp points to the same storage as numbers.

Regards, Alex

0
 
NightBladerAuthor Commented:
Ah, now I understand, Thanks! :D
Sorry, I gave the expert points to nonubik, before. :(
0
 
itsmeandnobodyelseCommented:
>> Sorry, I gave the expert points to nonubik, before.

No problem. However you shouldn't use malloc and realloc in C++ as it is native C and shouldn't mixed up with new and delete.

Regards, Alex

0
All Courses

From novice to tech pro — start learning today.