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.
Related
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 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.
This question already has answers here:
Representing a 2D array as a 1D array [duplicate]
(5 answers)
Closed 9 years ago.
I have a jagged 2D array, the rows aren't all the same length:
int sizes[100];
//init sizes
unsigned char *p = [100];
for(unsigned int i = 0; i < 10; i++)
{
p[i] = (unsigned char*)malloc(sizeof(char)*sizes[i]);
for(unsigned int j = 0; j < sizes[i]; j++)
p[i] = j;
}
I use the array like this:
p[x][y]
How can I simulate this array to 1D?
I assume that if you want to access your "2D array" as a one D matrix, you expect that as you increment your index by 1, you access the next element in the array (and will automatically go to the next line when you run off the edge). The right way to do this is by changing the way you allocate the array. I'll try to show how this is done - this is just C, not C++. It's probably more appropriate since you were using malloc anyway. I am also thinking that you have a pretty serious error in your code, in that you are creating a char * pointer p, yet expect to use it in
p[x][y];
for which you would need a char **, obviously. Let's try to make code that would do what you want:
int sizes[100];
//init sizes
unsigned char *p[100]; // without the == sign we create an array of 100 pointers
unsigned char *bigP; // the master pointer
int totalLength = 0;
int ii;
for(ii=0; ii<100; ii++) totalLength += sizes[ii];
bigP = malloc(sizeof(char) * totalLength);
int offset = 0;
// make pointers p point to places along this big memory block:
for(ii = 0; ii < 100; ii++) {
p[ii] = bigP + offset;
offset += sizes[ii];
}
Now you can either address your array with
p[x][y];
or with
bigP[z];
where z can go from 0 to the maximum number of elements. Of course, in the process you don't know (when you are using the "1D" paradigm) in what row/column of the jagged array you are - you can't know that if you are truly in one dimension.
The key here is that the memory is allocated as a single contiguous block, and the pointers p are pointing to places in that block. This means you MUST NOT FREE p. You must only ever free bigP.
I hope this makes sense.
If you're looking for a way to map a two dimensional array onto a one dimensional space, then try...
int sizes[width*height];
void setPoint(int x, int y, int val) {
sizes[x*width + y] = val;
}
Notably the x*width + y indexing will give you the appropriate element in the one dimensional array.
Unless it is homework just download boost and use Boost.Matrix.
I got a question on pointer in C++ :
Write a function that computes the average value of an array of floating-point data:
double average(double* a, int size)
In the function, use a pointer variable, not an integer index, to traverse the array elements.
And here is my solution :
int main()
{
const int size = 5;
double num_array[] = {2,2,3,4,5};
double* a = num_array;
cout << average(a,size);
cout << endl;
system("PAUSE");
return 0;
}
double average(double* a,const int size)
{
double total = 0;
for (int count =0; count< size; count++){
total = total + *(a + count);
}
return total/size;
}
It works fine but I have question on the for loop on pointer in average function. If I replace the statement in for loop with :
total = total + a*;
(I thought we supposed to do like this to add up all the number in array but unfortunately it gives me the wrong answer)
So what does the *(a + count) do? If possible, can somebody please simply brief me on how it works?
Thanks in advance.
a is a pointer to a double.
If you write *a, this pointer gets dereferenced and you get the data where the pointer points at, i.e. the double value. Note that the asterisk has to be in front of the pointer. (It's a "prefix" unary operator.)
a* is no valid syntax (it tries to multiply a with something which still has to follow ...)
a + count is pointer arithmetic. It gives you a but with count numbers of elements offset to the original a pointer. So it now points to the count-th element in the array.
*(a + count) now dereferences exactly this pointer, which gives you the count-th element of the array.
a[count] is exactly the same; it's just a nicer syntax.
Note: You can also use a++ in your loop. What it does is it increments the pointer by one position in the array. The next time you dereference a using *a, it returns the next entry. So your loop can be rewritten like this:
double total = 0;
for (int count = 0; count < size; count++){
total = total + *a; // Access the element a currently points to
a++; // Move the pointer by one position forward
}
You can even combine the increment and dereferencing operations into one expression. The postfix-increment syntax a++ will return the old pointer and increment the pointer by one position. Dereferencing a++ now means that you dereference the old pointer.
double total = 0;
for (int count = 0; count < size; count++){
total = total + *(a++);
}
The second note I want to give you is that you don't need your integer variable here to count the element. Since your pointer now already carries the information, your counter is now only used to stop the loop. This can also be done by comparing the pointer with some "end pointer", which we keep in a variable:
double total = 0;
double *end = a + size; // Store the end of the array
while(a < end) {
total = total + *(a++);
}
As you can see, I converted the for loop into a while loop since I no longer need to initialize or increment something (remember: going to the next entry of the array is done in the body!).
I hope this illustrates pointer arithmetic a little bit. You can "calculate" with pointers similarly as with indexing variables (your count variable). You can even subtract them to calculate offsets between pointers, for example.
* is the dereferencing operator, operating on the address a increased by count.
Read Pointers.
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.