I have problems deleting an array
int calc_mode (vector<int> array, int arrSize) {
int ipRepetition = new int[arrSize];
int j;
bool bFound;
for(int i =0; i<arrSize; i++) {
ipRepetition [i] = 0;
j=0;
bFound = false;
while ( j<i && array[i] != array[j] ) {
if(array[i] != array[j]) {
++j;
}
}
}
int iMaxRepeat = 0;
for(int i =0; i<arrSize; i++) {
if(ipRepetition[i] > ipRepetition[iMaxRepeat] ) {
iMaxRepeat = i;
}
}
delete [] ipRepetition; //compiler is complaining here
return array[iMaxRepeat];
}
Error : Cannot delete 'ipRepetition' ....Can you please point out what I missed?
Sometimes the best answer is to unask the question. Instead of hand-allocating that array of int, use another vector<int>.
int ipRepetition = new int[arrSize];
It's not correct. ipRepetition must be pointer.
int* ipRepetition = new int[arrSize];
You need an int* instead of an int.
int* ipRepetition = new int[arrSize];
Along with #Pete Becker's (IMO, excellent) suggestion, I'd consider using some standard algorithms to do most of the work. std::mismatch can tell you each location where a run ends (i.e., where a value in the input is not equal to the previous value). Along with std::distance (or just subtraction, since you're using random access iterators) that will tell you the length of each run fairly directly.
Once you've found the run lengths, you can use std::max_element to find the longest of them.
Related
Disclosure: I'm trying to solve a challenge with strict time and memory limits. I would normally use vectors and strings, but here I need the fastest and smallest solution (with vectors it actually ran above the time limit), so I turned to dynamic arrays of char*.
The relevant parts of my code:
char** substrings(string s, int* n){
*n = 0;
...
////////////////////////////////
char** strings = new char*[*n];
////////////////////////////////
for (int i = 0; i < s.length(); i++){
for (int j = 1; j < s.length() - i + 1; j++){
...
strings[si] = tmp;
...
}
}
return strings;
}
int main(){
...
for (int ti = 0; ti < t; ti++){
cin >> s;
char** substr = substrings(s, &n);
...
for (int i = 0; i < n; i++){
delete substr[i];
}
}
return 0;
}
Everything runs just fine without deleting the array (of arrays), but that is unacceptable, so how do I go about this? I've tried a lot of variations that seemed logical but I get runtime errors.
It is similar to allocating, but in reverse order, and using delete[] instead of new[]:
for(int i = 0; i < LENGTH; i++)
delete[] strings[i]; // delete each pointer in char** strings
delete[] strings; // finally delete the array of pointers
I assumed here that LENGTH is the length of the array of pointers to char*. So it looks that you only perform the first round of de-allocation
for (int i = 0; i < n; i++){
delete substr[i]; // need delete[] substr[i] here
but with delete instead of delete[], you need delete[] substr[i] instead, as my guess is that substr[i] is a char* pointer pointing the first element of an array of chars allocated by new[]. You finally need the additional
delete[] substr;
I am trying to shrink an array of *bool but I am not sure if it is being deleted correctly.
This is my source code...
bool *oldStore;
void shrinkArray(int i)
{
int k;
bool *newStore;
for(k=0; k<i; k++)
{
newStore[k] = oldStore[k];
}
for(; k<originalSize; k++)
{
delete[] oldStore[k];
}
delete[] oldStore;
oldStore = newStore;
}
For example, if I wanted to shrink the array to 5 and the original size of the array was 15, it would keep the first five and delete the last ten, however I am not too sure if my memory is being managed correctly.
Think about you method design before going into the coding specifics. I assume you have an ínt array that you new somewhere in your code.
Think about who "owns" this array? It's probably no good idea to create the int array at some place and to simply delete[] it somewhere else. Check out the following links: What is a smart pointer and when should I use one?
Think about what should happen to your newStore array. Is it supposed to replace the oldStore or do you want both arrays to exist in parallel. If you simply put the newStore on the heap who/when and where are you going to delete[] it again.
Simplest code would be:-
void shrinkArray(int i)
{
int k;
bool *newStore = new bool[i];
for(k=0; k<i; k++)
{
newStore[k] = oldStore[k];
}
delete [] oldStore; //assuming oldstore was allocated using new []..
oldStore = newStore;
}
Your code is wrong. You declared pointer newStore but neither initialize it nor allocated memory that would be pointed to by this pointer
bool *newStore;
So the next loop has undefined behaviour.
for(k=0; k<i; k++)
{
newStore[k] = oldStore[k];
}
Moreover if each element of the array pointed to by pointer oldStore has type bool * that is in turn is a pointer then oldStore itself shall have type bool **
If so then the correct function could look like
void shrinkArray( int n )
{
if ( n < originalSize )
{
bool **newStore = new bool * [n];
int i = 0;
for ( ; i < n; i++ ) newStore[i] = oldStore[i];
for ( ; i < originalSize; i++ ) delete oldStore[i];
delete [] oldStore;
oldStore = newStore;
originalSize = n;
}
}
Take into account that oldStore also shall have type bool **.
Otherwise if each element of the original array has type bool then the code will look like
void shrinkArray( int n )
{
if ( n < originalSize )
{
bool *newStore = new bool [n];
int i = 0;
for ( ; i < n; i++ ) newStore[i] = oldStore[i];
// Or
// std::copy( oldStore, oldStore + n, newStore );
delete [] oldStore;
oldStore = newStore;
originalSize = n;
}
}
Take into account that it would be much better and simpler to use standard container std::vector<bool *> or std::vector<bool> depending on the type of the element of the container.
Ok, so I'm quite new to C++ and I'm sure this question is already answered somewhere, and also is quite simple, but I can't seem to find the answer....
I have a custom array class, which I am using just as an exercise to try and get the hang of how things work which is defined as follows:
Header:
class Array {
private:
// Private variables
unsigned int mCapacity;
unsigned int mLength;
void **mData;
public:
// Public constructor/destructor
Array(unsigned int initialCapacity = 10);
// Public methods
void addObject(void *obj);
void removeObject(void *obj);
void *objectAtIndex(unsigned int index);
void *operator[](unsigned int index);
int indexOfObject(void *obj);
unsigned int getSize();
};
}
Implementation:
GG::Array::Array(unsigned int initialCapacity) : mCapacity(initialCapacity) {
// Allocate a buffer that is the required size
mData = new void*[initialCapacity];
// Set the length to 0
mLength = 0;
}
void GG::Array::addObject(void *obj) {
// Check if there is space for the new object on the end of the array
if (mLength == mCapacity) {
// There is not enough space so create a large array
unsigned int newCapacity = mCapacity + 10;
void **newArray = new void*[newCapacity];
mCapacity = newCapacity;
// Copy over the data from the old array
for (unsigned int i = 0; i < mLength; i++) {
newArray[i] = mData[i];
}
// Delete the old array
delete[] mData;
// Set the new array as mData
mData = newArray;
}
// Now insert the object at the end of the array
mData[mLength] = obj;
mLength++;
}
void GG::Array::removeObject(void *obj) {
// Attempt to find the object in the array
int index = this->indexOfObject(obj);
if (index >= 0) {
// Remove the object
mData[index] = nullptr;
// Move any object after it down in the array
for (unsigned int i = index + 1; i < mLength; i++) {
mData[i - 1] = mData[i];
}
// Decrement the length of the array
mLength--;
}
}
void *GG::Array::objectAtIndex(unsigned int index) {
if (index < mLength) return mData[index];
return nullptr;
}
void *GG::Array::operator[](unsigned int index) {
return this->objectAtIndex(index);
}
int GG::Array::indexOfObject(void *obj) {
// Iterate through the array and try to find the object
for (int i = 0; i < mLength; i++) {
if (mData[i] == obj) return i;
}
return -1;
}
unsigned int GG::Array::getSize() {
return mLength;
}
I'm trying to create an array of pointers to integers, a simplified version of this is as follows:
Array array = Array();
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject(&j);
}
Now the problem is that the same pointer is used for j in every iteration. So after the loop:
array[0] == array[1] == array[2];
I'm sure that this is expected behaviour, but it isn't quite what I want to happen, I want an array of different pointers to different ints. If anyone could point me in the right direction here it would be greatly appreciated! :) (I'm clearly misunderstanding how to use pointers!)
P.s. Thanks everyone for your responses. I have accepted the one that solved the problem that I was having!
I'm guessing you mean:
array[i] = &j;
In which case you're storing a pointer to a temporary. On each loop repitition j is allocated in the stack address on the stack, so &j yeilds the same value. Even if you were getting back different addresses your code would cause problems down the line as you're storing a pointer to a temporary.
Also, why use a void* array. If you actually just want 3 unique integers then just do:
std::vector<int> array(3);
It's much more C++'esque and removes all manner of bugs.
First of all this does not allocate an array of pointers to int
void *array = new void*[2];
It allocates an array of pointers to void.
You may not dereference a pointer to void as type void is incomplete type, It has an empty set of values. So this code is invalid
array[i] = *j;
And moreover instead of *j shall be &j Though in this case pointers have invalid values because would point memory that was destroyed because j is a local variable.
The loop is also wrong. Instead of
for (int i = 0; i < 3; i++) {
there should be
for (int i = 0; i < 2; i++) {
What you want is the following
int **array = new int *[2];
for ( int i = 0; i < 2; i++ )
{
int j = i + 1;
array[i] = new int( j );
}
And you can output objects it points to
for ( int i = 0; i < 2; i++ )
{
std::cout << *array[i] << std::endl;
}
To delete the pointers you can use the following code snippet
for ( int i = 0; i < 2; i++ )
{
delete array[i];
}
delete []array;
EDIT: As you changed your original post then I also will append in turn my post.
Instead of
Array array = Array();
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject(&j);
}
there should be
Array array;
for (int i = 0; i < 2; i++) {
int j = i + 1;
array.addObject( new int( j ) );
}
Take into account that either you should define copy/move constructors and assignment operators or define them as deleted.
There are lots of problems with this code.
The declaration void* array = new void*[2] creates an array of 2 pointers-to-pointer-to-void, indexed 0 and 1. You then try to write into elements 0, 1 and 2. This is undefined behaviour
You almost certainly don't want a void pointer to an array of pointer-to-pointer-to-void. If you really want an array of pointer-to-integer, then you want int** array = new int*[2];. Or probably just int *array[2]; unless you really need the array on the heap.
j is the probably in the same place each time through the loop - it will likely be allocated in the same place on the stack - so &j is the same address each time. In any case, j will go out of scope when the loop's finished, and the address(es) will be invalid.
What are you actually trying to do? There may well be a better way.
if you simply do
int *array[10];
your array variable can decay to a pointer to the first element of the list, you can reference the i-th integer pointer just by doing:
int *myPtr = *(array + i);
which is in fact just another way to write the more common form:
int *myPtr = array[i];
void* is not the same as int*. void* represent a void pointer which is a pointer to a specific memory area without any additional interpretation or assuption about the data you are referencing to
There are some problems:
1) void *array = new void*[2]; is wrong because you want an array of pointers: void *array[2];
2)for (int i = 0; i < 3; i++) { : is wrong because your array is from 0 to 1;
3)int j = i + 1; array[i] = *j; j is an automatic variable, and the content is destroyed at each iteration. This is why you got always the same address. And also, to take the address of a variable you need to use &
This is my structure which has two integer pointers aV and aT.
struct ADJP
{
int *aV;
int eV;
int nV;
int *aT;
int nT;
};
ADJP *Umb = NULL;
The allocation process of aV and aT is like this..
for(int i=0; i<nb; i++)
{
Umb[i].aV = new int[N];
for(int j=0; j<n; j++)
Umb[i].aV[j] = pIn[i].aV[j];
}
I want to remove one specific element from Umb array. for example I want to remove Umb[5], then how can I remove. I have tried with various mathods but got error due to allocated pointers I think. I have tried with follow method but its not working with this kind of struct array. It is working with struct array having no pointers.
int DeleteStructElement(int Index, ADJP *b, int N, int at)
{
for(int i=Index; i<N-1; i++)
memmove(&b[i], &b[i+1], (N-at-1)*sizeof*b); // moving the terms of array
N--; // updating new size
return N;
}
Have any idea how to remove an element from my struct array?
You will want to delete the arrays in the deleted element to release their memory:
delete[] b[Index].aV;
delete[] b[Index].aT;
Then, you only have to do a single memmove to remove the element.
memmove(&b[Index], &b[Index+1], (N-Index-1) * sizeof(b[Index])
EDIT: as Mahmoud points out, this doesn't use the at parameter in DeleteStructElement; I'm not sure what you intended that parameter to do.
int DeleteStructElement (int index, ADJP * b, int nb) {
delete [] (b[index].aV);
for (int i = index; i < nb - 1; ++i) {
b[i] = b[i+1];
}
return nb - 1;
}
Assuming you're really using C++, a destructor in ADJP would be much more straightforward than DeleteStructElement.
But if you're doing some interesting "C" with new/delete (perhaps a well-confined subset of C++?), then I'd suggest calling delete from within DeleteStructElement.
but got error due to allocated pointers I think
Answering this question might be much more important than others. I'm assuming this was a runtime error? Use a debugger to suss out just exactly where the fault was.
I am learning about pointers and the new operator in class.
In my readArray function I am to read in a size. Use the size to dynamically create an integer array. Then assign the array to a pointer, fill it, and return the size and array.
I believe I've gotten that part corrected and fixed but when I try to sort the array, i get the error "uninitialized local variable temp used."
The problem is though I get that error when I am trying to intialize it.
Any help appreciated thank you. Seeing my errors is very helpful for me.
#include <iostream>
using namespace std;
int* readArray(int&);
void sortArray(int *, const int * );
int main ()
{
int size = 0;
int *arrPTR = readArray(size);
const int *sizePTR = &size;
sortArray(arrPTR, sizePTR);
cout<<arrPTR[1]<<arrPTR[2]<<arrPTR[3]<<arrPTR[4];
system("pause");
return 0;
}
int* readArray(int &size)
{
cout<<"Enter a number for size of array.\n";
cin>>size;
int *arrPTR = new int[size];
for(int count = 0; count < (size-1); count++)
{
cout<<"Enter positive numbers to completely fill the array.\n";
cin>>*(arrPTR+count);
}
return arrPTR;
}
void sortArray(int *arrPTR, const int *sizePTR)
{
int *temp;
bool *swap;
do
{
swap = false;
for(int count = 0; count < (*sizePTR - 1); count++)
{
if(arrPTR[count] > arrPTR[count+1])
{
*temp = arrPTR[count];
arrPTR[count] = arrPTR[count+1];
arrPTR[count+1] = *temp;
*swap = true;
}
}
}while (swap);
}
You make temp an int pointer (uninitiialized), and then set the thing it points at (anything/nothing) to arrPTR[ccount]. Since you are using temp only to swap, it should be the same type as those being swapped, in this case: an int.
If it absolutely must be a pointer (there is no good reason for this, it's slow, confusing, adds potential for errors, and adds potential for memory leaks):
int *temp = new int; //make an int for the pointer to point at
bool *swap = new bool; //make an bool for the pointer to point at
do
{
//your code
}while (swap);
delete temp;
delete swap;
You declared temp as a pointer. You need to allocate it on the heap before dereferencing and assigning to it later. However perhaps a variable on the stack would be preferable?
FYI: You should be aware of the memory leak in readArray as well which is leaving callers responsible for calling delete []
Edit: I hope this will help clear up some of the other problems.
#include <iostream>
int* readArray(int&);
void sortArray(int*, int);
int main ()
{
int size(0); // use stack when possible
int *arrPTR = readArray(size);
sortArray(arrPTR, size);
// arrays are zero based index so loop from 0 to size
for (int index(0); index < size; ++index)
std::cout << arrPTR[index];
delete [] arrPTR; // remember to delete array or we have a memory leak!
// note: because we did new[] for an array we match it with delete[]
// if we just did new we would match it with delete
system("pause");
return 0;
}
int* readArray(int& size)
{
std::cout << "Enter a number for size of array.\n";
std::cin >> size;
int *arrPTR = new int[size]; // all news must be deleted!
// prefer pre-increment to post-increment where you can
for(int count(0); count < size; ++count)
{
std::cout << "Enter positive numbers to completely fill the array.\n";
std::cin >> arrPTR[count];
}
return arrPTR;
}
// passing size by value is fine (it may be smaller than pointer on some architectures)
void sortArray(int *arrPTR, int size)
{
// you may want to check if size >= 2 for sanity
// we do the two loops to avoid going out of bounds of array on last iteration
for(int i(0); i < size-1; ++i) // the first to compare (all except last)
{
for(int j(i+1); j < size; ++j) // the second to compare (all except first)
{
// do comparison
if (arrPTR[i] > arrPTR[j]) // from smallest to biggest (use < to go from biggest to smallest)
{
// swap if needed
int temp(arrPTR[i]); // put this on stack
arrPTR[i] = arrPTR[j];
arrPTR[j] = temp;
}
}
}
}
temp is a "pointer to int, which you're not initializing. When you say *temp = ... you're actually assigning to whatever temp happens to be pointing, but since you haven't told it what to point to, it can write pretty much anywhere in the address space of your program.
Because of the way you're using them, it seems that temp and swap shouldn't be pointers at all, just a plain int and bool.
You didn't initialize the temp pointer do when you dereference it you are writing to a random part of memory. Temp doesn't need to be a pointer, it can just be an int. Just replace EVERY instance of *temp with temp.