Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I would like to change the size of array when it exceed its limit. I have created a function for that.
void AddElemenet( int i , int value){
if( i > index - 1){
int tmp = index;
double *new_arr;
while( i > tmp){
tmp*=2
}
new_arr = new double[tmp]();
for( int j = 0; j < index ; j++){
new_arr[j] = arr[j];
}
index = tmp;
delete[] arr;
arr = new_arr;
}
arr[i] = value;
}
index refers to the max size of an array ; and arr is dynamicly allocated array using new itself.
The problem is , that i am assigning arr to a local variable that get destroyed. I tried assignign it as refference or pointer using *arr=*new_arr
but nothing worked so far. How can i change the array using this local variable?
The various bugs in your implementation demonstrate why it is almost always a good idea to use the standard library. It would be very simple to adapt std::vector to this interface.
The essence of your problem is the confusion over what index means. (That's a terrible name for a member variable. It says nothing. Index of what? And actually, it's not an index; it's the size of the array. At least, that's what it should be.)
Suppose that your array has 4 elements, so index is 4 (based on the assumption that it is the size of the array). Now you want to AddElement(4, 42);. The condition in if( i > index - 1) is certainly true: i is 4, and index - 1 is 3. So the reallocation block will be entered. However, the first thing you do is tmp = index; while( i > tmp) tmp *= 2;. i is not greater than tmp -- both of them are 4 -- so the loop will never run and tmp will still be 4. Now you allocate a new array with four elements, copy the existing four elements to it, "update" index to 4 (its current value), and delete the old array. Right afterwards, you attempt to set the element with index 4 to 42. But the array only has four elements, so that is Undefined Behaviour.
Since you have not actually changed the size of the array, or the value of index which indicates its size, your later attempt to print the values of the array will stop at its actual size, ignoring the value you modified outside the storage area of the array (which may belong to some other datastructure, so its value is meaningless anyway.)
If you rename index as size and tmp as new_size, the code is much clearer, and the fix is also clear:
if (i >= size) {
size_t new_size = size;
while (i >= new_size) new_size *= 2; /* NOT > */
double* new_array = new double[new_size]();
for (size_t j = 0; j < size; ++j) new_array[j] = array[j];
array = new_array;
size = new_size;
}
array[i] = value;
This would all have been much simpler and less error-prone if you used a std::vector:
class MyVector {
public:
void AddElement(size_t i, double value) {
if (i >= data_.size()) data_.resize(i + 1);
data_[i] = value;
}
/* Many implementation details omitted */
private:
std::vector<double> data_;
}
std::vector <int> list;
void AddElemenet(int value)
{
list.push_back (value);
}
Just use vector's. Array's size is fixed. Vector's size is dynamic.
Related
I'm a novice programmer who is learning C++.
Below are the relevant parts of my code. VSCode throws an error 'size' not initialized with a constant expression, and I'm unclear about the underlying error(s) in which I'm making.
int min, max;
min = max = 0;
for(int i=0;i<a.size();i++){
if(a[i]/int(pow(10,exp))%10>max) max = a[i];
if(a[i]/int(pow(10,exp))%10<min) min = a[i];
}
return std::array<int,2> {min,max};
}
std::vector<int> radixSort(std::vector<int> a){
int xp,maxval;
xp = maxval = 0;
int xpv = pow(10, xp);
for(int i=0;i<a.size();i++){
if(a[i]>maxval) maxval = a[i];
}
while(maxval/pow(10/xp) != 0){
std::array<int, 2> rg = findRange(a,xp);
int min = rg[0];
int size = rg[1]-rg[0]+1; //error at rg[1]: attempt to access storage one position past the end of an array of 1 elements
std::array<int,size> count;// Variable size cannot be used as constant
...
I'd like to clarify a few details:
I've returned an array size 2 with 2 elements {max,min} from my function findRange. So why is it that the compiler only interprets it as one? Changing the function return type to std::vector doesn't seem to fix the problem.
I realized that array sizes need to be fixed at compile time, but when I put const or constexpr infront of a size variable it doesn't fix the problem.
Feel free to point out any other mistakes in my code. Thanks!
EDIT: Changed int i to int i=0 in the first for loop
it is just because of array of size 2 with 2 elements try it with inheritance concept
I am trying to create an array, which doubles every time it is completely filled.
#include <iostream>
using namespace std;
int* array_doubler(int* array, int size){
int *new_array = new int[size*2];
for(int i = 0; i < size; i++){
new_array[i] = array[i];
}
delete[] array;
return new_array;
}
int main()
{
int N = 10; // Size of array to be created
int *array = new int[0];
for(int i = 0; i < N; i++)
{
if(array[i] == '\0')
array = array_doubler(array, i);
array[i] = i*2;
}
//Printing array elemensts
for(int i = 0; i < N; i++)
cout << array[i] << '\t';
cout << '\n';
return 0;
}
Problem is when I create dynamic memory with new, all the spots have the null character \0 value in them (not just the last spot). i.e. If i write:
int* p = new int[5];
then all the 5 blocks in memory p[0],p[1],p[2],p[3],p[4],p[5] have \0 in them, not just the p[5]. So the if(array[i] == '\0') in my main() calls array_doubler for every single iteration of for loop. I want it to fill the available spots in the array first and when it reaches the last element, then call array_doubler.
Problem is when I create dynamic memory with new, all the spots have the null character \0 value in them (not just the last spot).
Actually they have undefined values in them. 0 is a valid value for them to have, but tomorrow the compiler might suddenly decide that they should all have 1 instead of 0.
If you want to detect the end of an array, then you have to remember how big the array is. C++ doesn't do it for you. Actually, it does do it for you if you use std::vector, but I suppose that's not the point of this exercise.
I'm not sure why you'd want to do this, as std::vector offer this kind of feature, and are more idiomatic of c++ (see isocpp faq on why C-style array are evil).
One of the issue of C-style array is the fact that they donĀ“t know their own size, and that they don't have default value, thus stay uninitialized.
If for some reason you need to not use std::vector, the next best solution would be to wrap the array with it's size in a structure or a class (which is kinda what std::vector is doing), or to initialize your array using std::memset (which is the C function you would use if you were in C).
Do keep in mind that this is not considered as good practices, and that the STL offer plenty of solution when you need containers.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have made an array filled with randomized ints. Im trying to find out the biggest & smalest elements in it by using pointers in two different functions.
But one of my problem is that when I compare to find the lowest element the first element in my array changes to the found min-value.
// Compare to find min value
min = array;
for (int i = 0; i < size; i++)
{
if (*min > *(min + i))
*min = *(min + i);
}
// show array using pointer
ptr = resetArray; // Fill int *ptr with original array
for (int i = 0; i < size; i++)
{
std::cout << *(ptr + i) << std::endl;
}
After this comparment is done it moves the *min value to the begining of the array replacing the first element in it.
Sorry for my bad English!
It looks like you might have a misconception about how pointers work (or maybe it's a simple mistake).
A pointer such as int* is not a variable for keeping track of an int. An int* pointer allows you to access some other variable that keeps track of an int. The pointer "points" at some other memory location; that is what they are for.
In your case, min is pointing to the integer in the array. min is not some separate storage for an integer. The fact that array[i] == *min is not merely because they happen to have equivalent integers; even more than that, they are pointing to the same memory location. If you change one, you change the other since they are the same memory location.
What you probably want to do instead, assuming you want to keep your current loop&pointer style you have, is to have a separate pointer for iterating over the array and set min (not *min) equal to the iterating pointer. That is:
int* iterator;
for(...)
if(*iterator < *min)
min = iterator
iterator += 1;
Personally, I would just access the array with array[i]
You let the pointer min point to the first value of the array, hence this value gets overwritten. Instead you should declare min as of the non-pointer type that array elements are of, e.g.:
auto min = array[0];
for (int i = 1; i < size; i++)
{
if (min > array[i])
min = array[i];
}
In any case, since you use c++, you might consider using the function std::minmax_element.
I have this function in my custom dynamic array class that allows the user to insert another array into this one. It works, but I'm like 99% sure that this is not the fastest solution, and I'm wondering if it is possible to combine the two for loops to increase peformance? If so, how? I'm kinda stuck.
thanks in advance.
void insertrange(T item[], int sizerange, int index)
{
int k = this->size;
int j = 0;
if(this->size + sizerange >= this->capacity) //if the size + added size are bigger than the capacity
{
this->enlarge(this->capacity + sizerange); //enlarge the array
}
for(k; k >= index; k--) //for every element from the end to the index where to add the new array
{
this->array[k + sizerange] = a[k]; //replace the element to his new spot
}
for(j; j < sizerange; j++) //vor every element in the new array
{
this->array[index + j] = item[j]; //place it in the new spot
}
size += sizerange;
}
I think the key is that you don't have to copy the empty cells.
void insertrange(T item[], int sizerange, int index)
{
// This actually points past the end of the current array, right?
int onePastLastEntry = this->size;
// Still need to make sure the new array is large enough
if(this->size + sizerange >= this->capacity) //if the size + added size are bigger than the capacity
{
this->enlarge(this->capacity + sizerange); //enlarge the array
}
// you should be able to go forward instead of backwards
for(i = index; i < onePastLastEntry ; i++)
{
// move the current element
this->array[i + sizerange] = a[i];
// then copy the new value
this->array[i] = item[i - index];
}
You could actually do the loop from zero, going to onePastLastEntry - index as well, but that makes the math weird:
// you should be able to go forward instead of backwards
for(i = 0; i < onePastLastEntry - index; i++)
{
// now you have to add the index in two places here
this->array[i + index + sizerange] = a[i + index];
// and add the index in the copy as well
this->array[i + index] = item[i];
}
The only possible performance benefit I see is doing less dynamic allocation every time the array gets larger. It is better in most cases to multiply the capacity by 2 every time you need to reallocate.
You have one extra copy in your k for loop. The k index should start at size-1, not size, so you are copying one extra element beyond the end of your array. However, this will provide negligible speedup. If serious performance improvement is needed, you should look into optimizing the enlarge function or use a different data structure than an array.
You can move the elements, instead of copying them:
for(k; k >= index; k--)
{
this->array[k + sizerange] = std::move(a[k]);
}
Another possible improvement, especially for classes that have an expensive default constructor, is to construct T in place, using the move constructor. When you allocate, instead of allocating with new T[], which default constructs every element, allocate raw bytes with new char[] or malloc. Then you can use placement new to move construct the object on the spot.
i have created a map called select_p and vector of this map is called pts. i have stored data in a array and i want to pushbcak these data into my vector of map. i tried this by inserting value of array into new vector and then pushback into my map.but it is not working please help me to correct these codes? thanks
#include<iostream>
#include<cstdlib>
#include <map>
#include <vector>
using namespace std;
int main()
{
int M=7;
int N=6;
int i=0;
int * temp;
map<int,vector<int> > select_p;
vector<int>pts;
for (int m=0; m<M; m++)
{
for (int n=0; n<N; n++)
{
vector<int>id;
if (n==0 && m==5)
{
temp = new int[3,i+N,i+N+1,i+1];
unsigned ArraySize = sizeof(temp) / sizeof(int);
id.insert(id.begin(),temp[0], temp[ArraySize]);
select_p[i].push_back(id);
}
i++;
}
}
delete[] temp;
system("PAUSE");
return 0;
}
for (int m=0; m<M; m++) {
for (int n=0; n<N; n++) {
if (n==0 && m==5) {
Why are you looping when you only actually do anything for a single pair of values of m and n? The loops are completely useless here; you would get the same effect by just setting n = 0 and m = 5.
temp = new int[3,i+N,i+N+1,i+1];
Whatever you think this does, that's not what it does. This is equivalent to temp = new int[i+1];. The rest of the expression inside of the [] has no effect.
That said, you should not use new to create arrays in your program. Use std::vector; it is far easier to use correctly.
unsigned ArraySize = sizeof(temp) / sizeof(int);
This does not work. When you dynamically allocate an array, you are responsible for keeping track of how many elements are in it. Given a pointer to a dynamically allocated array (like temp here) there is no way to determine the number of elements in the array.
What you have is equivalent to sizeof(int*) / sizeof(int), which is not going to do what you expect.
id.insert(id.begin(),temp[0], temp[ArraySize]);
std::vector::insert takes a range of iterators: you have provided it with two values. Presumably you want to use temp, which points to the initial element of the dynamically allocated array, and temp + i + 1, which points one past the end of the array. That said, since you haven't set the values of the elements in the array, you are copying uninitialized memory, which probably isn't what you mean to do.
select_p[i].push_back(id);
select_p[i] is a std::vector<int>. std::vector<int>::push_back() takes a single int that is appended to the sequence. Presumably you just mean to use assignment to assign id to select_p[i].
You should get a good introductory C++ book if you want to learn to program in C++. I am sorry to say that your program is nonsensical.