[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 372
  • Last Modified:

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.
0
NightBlader
Asked:
NightBlader
  • 10
  • 8
  • 3
  • +4
1 Solution
 
__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
 
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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:
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
 
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

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 10
  • 8
  • 3
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now