Solved

An Access Violation problem.

Posted on 2004-04-01
27
361 Views
Last Modified: 2010-04-01
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.
0
Comment
Question by:NightBlader
  • 10
  • 8
  • 3
  • +4
27 Comments
 

Expert Comment

by:__Julien__
ID: 10730710
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
 
LVL 16

Expert Comment

by:nonubik
ID: 10730725
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
 
LVL 10

Expert Comment

by:Sys_Prog
ID: 10730730
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
 
LVL 16

Expert Comment

by:nonubik
ID: 10730739
don't mind my commnet, I wad thinking at something totaly else ...
I saw cin>>count.... Obviously I saw wrong
0
 

Author Comment

by:NightBlader
ID: 10730743
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
 
LVL 16

Expert Comment

by:nonubik
ID: 10730784
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
 
LVL 16

Accepted Solution

by:
nonubik earned 100 total points
ID: 10730800
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
 
LVL 16

Expert Comment

by:nonubik
ID: 10730809
and a free(numbers); after the while loop.
and I think you meant cout<<"\nThe average: "<<avg/count;
0
 
LVL 1

Expert Comment

by:oferh
ID: 10730826
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
 

Author Comment

by:NightBlader
ID: 10730829
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
 

Author Comment

by:NightBlader
ID: 10730836
oferh, it doesnt. :/
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 10730838
__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
 
LVL 16

Expert Comment

by:nonubik
ID: 10730842
my mistake.
double * numbers = (double *)malloc(sizeof(double));
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:NightBlader
ID: 10730851
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
 
LVL 16

Expert Comment

by:nonubik
ID: 10730855
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
 

Author Comment

by:NightBlader
ID: 10730860
now the same mistake for:
numbers = realloc(numbers, (count+1)*sizeof(double));
0
 
LVL 16

Expert Comment

by:nonubik
ID: 10730869
the same correction
numbers = (double *)realloc(numbers, (count+1)*sizeof(double));
0
 

Author Comment

by:NightBlader
ID: 10730874
Ah, now it works, Thanks!
0
 
LVL 16

Expert Comment

by:nonubik
ID: 10730880
the pleasure was mine..
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 10730883
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
 
LVL 17

Expert Comment

by:rstaveley
ID: 10730889
Forgot to initialise the total, but you know I meant to.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10730920
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
 

Author Comment

by:NightBlader
ID: 10730977
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
 
LVL 16

Expert Comment

by:nonubik
ID: 10731005
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
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10731010
>> 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
 

Author Comment

by:NightBlader
ID: 10731026
Ah, now I understand, Thanks! :D
Sorry, I gave the expert points to nonubik, before. :(
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
ID: 10731118
>> 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

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now