I was trying to get used to the dynamic array in class to which I get the result to the output but get a core dump error.I get the output correct but at last of the output after compiling I get this core dump.
Output is
Enter the size of array: 4
Enter the numbers of array: 20
21
22
23
The element of the array is
20
21
22
23
munmap_chunk(): invalid pointer
Aborted (core dumped)
Here is the program I wrote:
class Array
{
private:
int *arr;
int size;
public:
Array(int sizes, int at[])
{
size = sizes;
arr = new int[size];
for (int i = 0; i < size; i++)
{
arr[i] = at[i];
}
}
Array()
{
size = 0;
}
~Array()
{
std::cout << "Destructor worked.";
delete[] arr;
}
void getarray()
{
std::cout << "Enter the size of array: ";
std::cin >> size;
setsize(size);
std::cout << "Enter the numbers of array: ";
for (int i = 0; i < size; i++)
{
std::cin >> arr[i];
}
}
void setsize(int sizes)
{
size = sizes;
}
void output(std::ostream& outs)
{
outs << "The element of the array is " << std::endl;
for (int i = 0; i < size; i++)
{
outs << arr[i] << std::endl;
}
}
};
I am still not good at dynamic array and I thought of using vectors. It will be great if anyone can show me what the problem with this problem is or any easier method for doing the same.
Assuming that your main() is somewhat like:
int main(void) {
Array foo; // or Array foo(bar, baz);
foo.getarray();
foo.output(std::cout);
}
The main problem here is that your constructor gets called before your getarray() method. And since you are already allocating memory inside your constructor,
void getarray() {
...
// Changing size, and iterating over it
...
}
is dangerous. If your newSize > size, the loop will try to access memory that does not belong to your program. If your newSize < size, it will not access all the elements.
How to overcome this?
Resize your array when you ask for size again.
Do not allocate memory inside the constructor, but allocate it inside getarr().
Do not resize your array inside getarray() at all, in which case you should not change your size.
All this really depends on the functionality you want to achieve. Say you want to have a fixed-sized array for the entire duration of your program, using a const qualifier with your size will help restrict un-authorized modifications.
If you want arrays which dynamically grow and shrink during your execution, you are better off using the std::vector container.
Related
I have a class array inside which I have declared an array its size and length. I am trying to merge two sorted arrays by creating the third array on the heap and both the sorted array will be merged on the third array. But whenever I create a new arr on heap the compiler gives me this error: request for member '..' in '..' which is of non-class type
class Array
{
public:
int A[10];
int length;
int Size;
};
void display(Array arr)
{
int i;
for(i=0;i<arr.length;i++)
{
cout<<arr.A[i]<<" ";
}
}
void Merge(Array *arr1,Array *arr2)
{
int i,j,k;
i=j=k=0;
int *arr3;
arr3=new int[10];
while(i<arr1->length && j<arr2->length)
{
if(arr1->A[i]<arr2->A[j])
arr3->A[k++]=arr1->A[i++];
else
arr3->A[k++]=arr2->A[j++];
}
for(;i<arr1->length;i++)
{
arr3->A[k++]=arr1->A[i];
}
for(;j<arr2->length;j++)
{
arr3->A[k++]=arr1->A[j];
}
}
int main()
{
Array arr1{{1,3,5,7},4,4};
Array arr2{{2,4,6,8},4,4};
Array *arr3;
arr3=Merge(&arr1,&arr2);
display(*arr3);
return 0;
}
The root cause of all your problems is that you use C-Style array with a magical size 10. Like in int A[10];. This is a major problem and should be avoided in C++.
Additionally, and the same, In C++ we usually do not use raw pointer for owned memories or newand such stuff.
Anyway. The design will never work, if the number of elements in both Array classes is greater then 5. Because then you will definitely get an out of bounds problem.
You must use a std::vector.
So, all bad. But I know that I will hear now, that the teacher said, no vector but new. The teacher should be fired or begin to teach C instead of C++.
Anyway again, I will fix the major bugs for you. But the sorting algorithm will work neither.
So,
If you want to return an Array, then change the signature of your function aand return an Array.
You do want to have a new Array, not new intes. So, please allocate a new Array instead.
Do not forget to release the newed Arrary at then end.
Set size and length of the new array.
Refactor your complete code.
Code example with some fixes:
#include <iostream>
class Array
{
public:
int A[10];
int length;
int Size;
};
void display(Array arr)
{
int i;
for (i = 0; i < arr.length; i++)
{
std::cout << arr.A[i] << " ";
}
}
Array* Merge(Array* arr1, Array* arr2)
{
int i, j, k;
i = j = k = 0;
Array *arr3 = new Array;
while (i < arr1->length && j < arr2->length)
{
if (arr1->A[i] < arr2->A[j])
arr3->A[k++] = arr1->A[i++];
else
arr3->A[k++] = arr2->A[j++];
}
for (; i < arr1->length; i++)
{
arr3->A[k++] = arr1->A[i];
}
for (; j < arr2->length; j++)
{
arr3->A[k++] = arr1->A[j];
}
arr3->length = arr1->length + arr2->length;
return arr3;
}
int main()
{
Array arr1{ {1,3,5,7},4,4 };
Array arr2{ {2,4,6,8},4,4 };
Array* arr3;
arr3 = Merge(&arr1, &arr2);
display(*arr3);
delete[]arr3;
return 0;
}
I need some help since I'm new to c++, I have a homework question where we should read a name to a char[] and then place that input inside a dynamic array, sort the dynamic array, and then terminate the allocated memory. We have to work with a half-done written program and I don't think I'm getting the input incorrectly in the dynamic array and I have a problem with deallocating memory could someone help with some tips maybe? My contribution to the code is highlighted in ** ** thanks!
const int BUFLEN = 100; // Max length of reading buffer
void sort(char* friendList[], int n); // n is the number of elements
void print(char* friendList[], int n); // n is the number of elements
void terminate(char* friendList[], int n); // n is the number of elements
const int AMOUNT = 5;
int main()
{
char* friends[AMOUNT]; // Dynamic array with AMOUNT pcs of string pointers
char buff[BUFLEN] = { "" }; // Creates a string buffer (null terminated)
int count = 0;
while (count < AMOUNT) // enter AMOUNT number of friends
{
cout << "Name a friend: ";
cin.getline(buff, BUFLEN); // Temporary reading into string buffer
friends[count] = **new char[AMOUNT];** //. . . WRITE CODE allocating memory to the string
// WRITE CODE that adds loaded name to current location in the dynamic array
**strcpy(friends[count], buff);**
++count;
}
sort(friends, count); // Sorts the ‘count’ strings
print(friends, count); // Prints the ‘count’ first names
terminate(friends, count);// Releases all allocated memory space
return 0;
}
void sort(char* friendList[], int n)
{
// WRITE FUNCTION that sorts the strings in the friendList in alphabetical order!
**int result;
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - 1 - i; j++)
{
result = strcmp(friendList[j+1], friendList[j]);
if (result < 0)
swap(friendList[j+1], friendList[j]);
}
}**
}
void print(char* friendList[], int n)
{
// WRITE FUNCTION that prints ‘n’ names from the friendList on screen!
**for (int i = 0; i < n; i++)
{
cout << friendList[i] << " " << i << endl;
}**
}
void terminate(char* friendList[], int n)
{
// WRITE FUNCTION that releases all dynamically allocated memory!
**for (int i = 0; i < n; i++)
{
delete friendList[i];
}
delete [] friendList;
cout << "deleted! ";**
}
I see a few problems with this code:
In main():
not validating that cin.getline() is successful before using the contents of buff.
AMOUNT is the wrong size to use when allocating a new char[] to store in friends[]. The correct size should be either strlen(buff)+1 or cin.gcount().
In terminate() (not to be confused with std::terminate()):
delete[]'ing the input array itself, which was not allocated with new[] to begin with and thus must not be delete[]'ed.
Instead of this statement
friends[count] = new char[AMOUNT];
you need to write
friends[count] = new char[strlen( buff ) + 1];
Pay attention to that the array friends itself is not allocated dynamically. But each its element points to a dynamically allocated array. So the function terminate can look like
void terminate(char* friendList[], int n)
{
// WRITE FUNCTION that releases all dynamically allocated memory!
for (int i = 0; i < n; i++)
{
delete [] friendList[i];
friendList[i] = nullptr;
}
cout << "deleted! ";
}
template <class T>
class Vector {
int pos = 0;
int chunkSize;
T** p = new T*;
public:
Vector(int chunkSize = 1000) {
this->chunkSize = chunkSize;
p[0] = new T[chunkSize];
std::cout << &p[0] << std::endl;
}
~Vector() {
for (int i = 0; i < pos / chunkSize; i++) {
std::cout << &p[i] << std::endl;
delete [] p[i];
}
}
void pushBack(T val);
void display();
};
template<class T>
void Vector<T>::pushBack(T val) {
p[pos / chunkSize][pos % chunkSize] = val;
if (++pos % chunkSize == 0)
p[pos / chunkSize] = new T[chunkSize];
}
template<class T>
void Vector<T>::display() {
for (int i = 0; i < pos; i++)
std::cout << p[i / chunkSize][i % chunkSize] << " ";
std::cout << std::endl;
}
I was tinkering with some code today, and came up with the above. What I am trying to do is create something resembling a vector, by using fixed sized arrays, and just creating more as I need.
I usually program in Java, so memory management isn't my forte, and I am not sure that what I am doing is entirely okay. The vector is created fine, and I can add any number of values to it just fine. I can also display them, without issue, using the display function above. However, the destructor throws a SIGABRT when trying to delete any element, and that is why I am here, I don't know why I can't free memory I have allocated and have access to, although I guess one possibility is that I am writing and reading from memory I should not have access to. Those two cout statements print the same address for the 0th element, which I used to check that I was consistently looking at the same memory address.
Could someone explain to me either how to delete the elements properly, or why what I am doing is a huge mistake?
EDIT: The main class calls this code as follows.
int main() {
Vector<int> vec;
for (int i = 0; i < 1000000; i++)
vec.pushBack(i);
vec.display();
return 0;
}
The problem is that you only allocate space for one T* and store that in your p pointer. Once you push back chunksize elements, you write to p[1], which (since it past the end of the memory allocated for it) results in Undefined Behavior. Which includes running on apparently working for quite some time before it blows up.
You'll need to allocate additional space in the p array whenever you need to access additional elements there.
I want to declare a 2D Array without an initial size. It keeps on giving me an error:
Error C2078: too many initializes.
I have tried to dynamically allocate my array but nothing worked out so far as I am not too familiar with dynamic allocation. My question is If there is a possible way to declare an Array without an initial size and if so what is the most efficient way to do it ?
I wrote a simple program using pointers, new and delete functions. You can add more functionality to it.
#include <iostream>
using namespace std;
int main()
{
int size;
cout << "Input size of 2D array : ";
cin >> size;
int *ptr; // Declare Pointer
ptr = new int[size*size]; // Allocate memory of all elements in 2D array
for (int i = 0; i < size*size; i++) {
*(ptr + i) = 0; // Initialize every element to 0
}
cout << "Printing the 2D Array" << endl << endl;
int iterSize = 0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
cout << *(ptr + iterSize) << " ";
}
cout << endl;
}
delete [] ptr; // ptr memory is released
return 0;
}
Here is the output initializing all elements to 0:
my question is If there is a possible way to declare an Array without an initial size and if so what is the most efficient way to do it ?
Sure, you could provide a vector of vectors to represent a 2D array (let's say of integer values):
std::vector<std::vector<int>> my2DArray;
Well, regarding efficiency maybe performance and memory fragmentation wise it's better to wrap a 1D vector kept internally with an interface that allows 2D coordinate access.
That would require you to know and specify the dimension limits though.
So if you really want to keep a 2D structure without initial size the above mentioned vector of vectors is the way to go.
I am working on a paint program and i create an array of figures in a class
and i want to pass that array to another class and loop through it's elements
i dont understand the problem
the main class:
CFigure* FigureList[Figcount];
CFigure* getfiglist()
{
return *FigureList;
}`
and the other class include:
CFigure *P=pManager->Getfiglist();
for(int i=0;i<pManager->Getfigcount;i++)
{
*(p+i)->resize(factor); //displays error : operand of * must be a pointer
}
how should i access the array elements using the passed pointer and what did i do here that caused the error . thanks in advance
There is a lot to say about arrays in C++, here is some information that might help :
Native C++ arrays
if you create an array like so :
int array[10] = {0,1,2,3,4,5,6,7,8,9};
And you try to print the values of array, &array or &array[0] you will notice they are all the same values. This value is the adress of the first element in your array. There is no such thing as an array pointer, there is just a pointer to the first element.
As the other elements of your array follow the first, you can access them by adding 1 to the address of the first element (array+1) :
void print(int *array, int length)
{
for (int i=0 ; i<length ; i++){
cout << *(array+i) << endl;
}
}
int main()
{
int array[10] = {0,1,2,3,4,5,6,7,8,9};
print(array, 10);
}
It turns out that you can also use the regular expression to access your array elements and it will work fine :
void print(int *array, int length)
{
for (int i=0 ; i<length ; i++){
cout << array[i] << endl;
}
}
Vectors
That being said, if one is not careful with native arrays, the code may quickly get very nasty and hard to read... This is why you should use std::vector instead as suggested by #Ðаn.
Vectors have the particularity to be dynamic so you don't have to specify any size when you create them, and you can add as many elements as you want without caring about any pointer or memory stuff.
void print(vector<int> &v)
{
for (int i=0 ; i<v.size() ; i++){
cout << v[i] << endl;
}
}
int main()
{
vector<int> v = {0,1,2,3,4,5,6,7,8,9};
v.push_back(10);
v.push_back(11);
v.push_back(12);
print(v);
}
Links
You can read more about vectors here.
I didn't talk about it but there is also std::array.