In c++, we usually use memset to set all elements to zero like:
int a[5][5];
memset(a,0,sizeof(a));
What if I want set all int elements to 1?
memset(a, 1, sizeof(a));
doesn't work since I cannot just set all bytes to 1.
I wonder if there is similar function as memset to set all elements(NOT JUST BYTES) to a particular value.
Using std::fill will work, but you have to resort to using reinterpret_cast<>, which is often considered bad form:
#include <algorithm>
int a[5][5];
std::fill(reinterpret_cast<int*>(a),
reinterpret_cast<int*>(a)+(5*5),
1);
Alternatively, you could take the address of the first element, which is likewise clunky:
std::fill(&a[0][0],&a[0][0]+(5*5),1);
Related
Here is my code, I would need to fill in every element in the 2d array with the maximum size ( INT_MAX), however, my code was unable to work properly?
#include <iostream>
#include <string.h>
#include <limits.h>
using namespace std;
int main(){
int arr[10][10];
memset(arr,INT_MAX, sizeof (arr));
cout << arr[0][3];
//output = -1 instead of 2147483647
}
How do I modify my code such that I will be able to fill in an array with the max values?
C++ Standard Library has a function fill_n to fill arrays with n values.
#include <algorithm>
...
std::fill_n(&arr[0][0], 100, INT_MAX);
The number of values may be brittle here - if you change the size of the array in future, you have to remember to change the hard-coded 100 to a new correct value.
It's good enough for a quick hack. If you need something with long-term value, use the idea in this answer to a similar question.
Ok a very basic question, but I am stuck at it. I cannot figure out the extra mysterious value at the end of the array. I just tried to traverse the array through its base address, plain and simple. But the garbage value at the end of the array remains constant every time I execute it
g++ complier 64 bit machine.
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
void printarray(int * arr){
while(*(arr)){ cout<<*arr<<" "; arr++; }
cout<<endl;
}
int main(){
int arr[] = { 3,2,4,1,5 };
printarray(arr); // prints 3,2,4,1,5,32765
return 0;
}
EDIT 1: I understand that the while will terminate whenever it comes across a 0 in the array , or if no 0 is found will go insane . But still I would want you guys to look at the following test cases
3,2,0,4,1,5 // outputs 3,2
3,2,4,1,5,7,8,9 // outputs same array correctly
3,2,4,1,5,7,8,9,10 // outputs array+ 1 varying garbage at last
//observations, this method works for even sized arrays not containing
//0, while for odd it emits an additional garbage value.
My question is if the while only breaks at 0 , why does it break at
arrayLength+1 everytime ? Also what's with this even odd length ?
An array is not terminated in any special way. What you are trying to do is not working because while(*arr) relies on a wrong assumption: that there is a 0 element at the end of the array (a sentinel) but you declare the array a {3,2,4,1,5} so there is no end element.
I think your misconcept comes from the fact that you are not getting the point that an int* is just a memory address, whenever you increment it by ++arr you are basically adjusting it by sizeof(int). Nothing more, when you reach the end of the array then the address just points after the array, to whatever value could be there.
You get the extra element(s) because there is nothing about a pointer that tells the compiler how many elements the pointer points to. When you do
while(*(arr)){...}
The while loop will continue running untill *arr == 0. Since you array doesn't contain a 0 it will keep going past the end of the array untill it finds a 0. This is undefined behavior as you are accessing memory you do not own with that pointer.
I think you may be confusing how char arrays(c-strings) work compared to other data types. When you have
char arr[] = "something";
while(*(arr)){...}
This ends at the end of the array as c-strings get a null terminator(0) added to the end of the string automatically. This allows you to do things like the above loop as you know that null terminator will be there and if it is not then that is on the person you created the string.
An array decays into a pointer when passed to a function, and this function knows nothing about the array's length.
That while(*arr) stuff is incorrect. It will stop only when some value this pointer points to is zero. But who said a zero is placed at the end of an array?? When you increment arr, you can easily get out of bounds of your array (the function doesn't know its size!), and then *arr will give you whatever the heck is stored at the memory address arr points to at the moment.
To iterate over an array, pass the array itself and its length. Otherwise this will iterate over and over until the value of *arr will be zero.
Pointers aren't terminated in C++ by any character.
This works on other types like char* only because it's terminated by an \0(0).
An INT-Array u need to count the Elements before you can pass them into something like that, for example here with the ending 5 from your Pointer:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
void printarray(int * arr){
int *saved=arr;
while(*saved!=5)
{
cout<<*saved++<<" ";
}
*saved=0;
cout<<endl;
}
int main(){
int arr[] = { 3, 2, 4, 1, 5 };
printarray(arr); // prints now without ending 5.
return 0;
}
Otherwise, you need to pass the counter of elements.
There is no way C++ could know how many elements your pointer points to.
In Qt, I have a 3-D int-array (say ID[x][y][z]) which I need to set back to 0 during computation.
Is there an efficient way to do it without using a loop?
I need the reinitialization because I am running a specific algorithm with a simple cost-function to get an estimation for the following more detailed computation, and I want to use the same data structure. Simply overwriting the array is not an option, because the algorithm reads and checks entries before writing them.
Sooner or later there's going to be a loop, but you can delegate it to another and more optimized function.
Also, if the "3D array" is really an array of arrays of arrays of some basic type (like int or char), then all the memory is contiguous so you can use a single function call to clear all of the memory in one single call.
Now which function to use; In C++ there are basically two functions you can use: The old C memset function, and the C++ std::fill function. Both should work fine, with proper casting and size, to set all of the data to a specific value.
Under the hood it will (almost) always be a loop. Don't worry, a loop without branches is quite efficient.
If you go for more readable, you can use a function like memset or std::fill which hides the loop.
Have a look at the answers to this question: What's the safe way to fill multidimensional array using std::fill?
The users #JoachimPileborg and #GeorgSchölly have already explained in their answers which functions can be used to reinitialize an array. However, I'd like to add some sample code and explain a difference between std::fill() and memset().
I assume that you want to (re)initialize your array with 0. In this case you can do it as shown in the following code:
#include <xutility> // For std::fill().
int main(int argc, char* argv[])
{
const int x = 2;
const int y = 3;
const int z = 5;
const int arraySize = x * y * z;
// Initialize array with 0.
int ID[x][y][z] = {};
// Use the array...
// Either reinitialize array with 0 using std::fill()...
std::fill(&ID[0][0][0], &ID[0][0][0] + arraySize, 0);
// ...or reinitialize array with 0 using memset().
memset(&ID[0][0][0], 0, sizeof(ID));
// Reuse the array...
return 0;
}
However, if you want to initialize your array with another value (for example, 1), then you have to be aware of a crucial difference between std::fill() and memset(): The function std::fill() sets each element of your array to the specified value. The function memset(), in contrast, sets each byte your array to the specified value. This is why memset() takes the array size as number of bytes (sizeof(ID)).
If you initialize your array with 0, this difference doesn't cause a problem.
But, if you want to initialize each element of your array with a non-zero value, then you have to use std::fill(), because memset() will yield the wrong result.
Let's assume you want to set all elements of your array to 1, then the following line of code will yield the expected result:
std::fill(&ID[0][0][0], &ID[0][0][0] + arraySize, 1);
However, if you use memset() in the following way, then you get a different result:
memset(&ID[0][0][0], 1, sizeof(ID));
As explained above, this line of code sets every byte to 1. Therefore, each integer element of your array will be set to 16843009, because this equals the hexadecimal value 0x01010101.
What is the difference between this two array definitions and which one is more correct and why?
#include <stdio.h>
#define SIZE 20
int main() {
// definition method 1:
int a[SIZE];
// end definition method 1.
// defintion method 2:
int n;
scanf("%d", &n);
int b[n];
// end definition method 2.
return 0;
}
I know if we read size, variable n, from stdin, it's more correct to define our (block of memory we'll be using) array as a pointer and use stdlib.h and array = malloc(n * sizeof(int)), rather than decalring it as int array[n], but again why?
It's not "more correct" or "less correct". It either is xor isn't correct. In particular, this works in C, but not in C++.
You are declaring dynamic arrays. Better way to declare Dynamic arrays as
int *arr; // int * type is just for simplicity
arr = malloc(n*sizeof(int*));
this is because variable length arrays are only allowed in C99 and you can't use this in c89/90.
In (pre-C99) C and C++, all types are statically sized. This means that arrays must be declared with a size that is both constant and known to the compiler.
Now, many C++ compilers offer dynamically sized arrays as a nonstandard extension, and C99 explicitly permits them. So int b[n] will most likely work if you try it. But in some cases, it will not, and the compiler is not wrong in those cases.
If you know SIZE at compile-time:
int ar[SIZE];
If you don't:
std::vector<int> ar;
I don't want to see malloc anywhere in your C++ code. However, you are fundamentally correct and for C that's just what you'd do:
int* ptr = malloc(sizeof(int) * SIZE);
/* ... */
free(ptr);
Variable-length arrays are a GCC extension that allow you to do:
int ar[n];
but I've had issues where VLAs were disabled but GCC didn't successfully detect that I was trying to use them. Chaos ensues. Just avoid it.
Q1 : First definition is the static array declaration. Perfectly correct.
It is when you have the size known, so no comparison with VLA or malloc().
Q2 : Which is better when taking size as an input from the user : VLA or malloc .
VLA : They are limited by the environment's bounds on the size of automatic
allocation. And automatic variables are usually allocated on the stack which is relatively
small.The limitation is platform specific.Also, this is in c99 and above only.Some ease of use while declaring multidimensional arrays is obtained by VLA.
Malloc : Allocates from the heap.So, for large size is definitely better.For, multidimensional arrays pointers are involved so a bit complex implementataion.
Check http://bytes.com/topic/c/answers/578354-vla-feature-c99-vs-malloc
I think that metod1 could be little bit faster, but both of them are correct in C.
In C++ first will work, but if you want to use a second you should use:
int size = 5;
int * array = new int[size];
and remember to delete it:
delete [] array;
I think it gives you more option to use while coding.
If you use malloc or other dynamic allocation to get a pointer. You will use like p+n..., but if you use array, you could use array[n]. Also, while define pointer, you need to free it; but array does not need to free.
And in C++, we could define user-defined class to do such things, and in STL, there is std::vector which do the array-things, and much more.
Both are correct. the declaration you use depends on your code.
The first declaration i.e. int a[size]; creates an array with a fixed size of 20 elements.
It is helpful when you know the exact size of the array that will be used in the code. for example, you are generating
table of a number n up till its 20th multiple.
The second declaration allows you to make an array of the size that you desire.
It is helpful when you will need an array of different sizes, each time the code is executed for example, you want to generate the fibonacci series till n. In that case, the size of the array must be n for each value of n. So say you have n = 5, in this case int a [20] will waste memory because only the first five slots will be used for the fibonacci series and the rest will be empty. Similarly if n = 25 then your array int a[20] will become too small.
The difference if you define array using malloc is that, you can pass the size of array dynamically i.e at run time. You input a value your program has during run time.
One more difference is that arrays created using malloc are allocated space on heap. So they are preserved across function calls unlike static arrays.
example-
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n;
int *a;
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
return 0;
}
Yesterday I programmed a small piece code in C++ which contains a loop and an array. In the program I need to reset the array every time the loop starts over. However, if I use
memset(sum,sizeof(sum),0);
Then the array won't be reset to all 0. For this program I used:
for (i=0;i<sizeof(sum)/sizeof(int);i++) sum[i]=0;
instead.
However, I think a loop is not as clear as a function, and it requires an additional variable, not to mention this is a million times uncool than the wizardry of memset() function. Could you guys enlighten me on this?
You're actually writing the size of sum into the 0 first bytes.
You should be doing memset(sum,0,sizeof(sum)) instead.
(In other words, the arguments are target, data and length and you provided data and length in the wrong order.)
This is C++ so do it the C++ way with fill_n.
std::fill_n(&sum[0], sizeof(sum) / sizeof(sum[0]), 0);
The reason your memcpy didn't work is because, as noted in other answers, you swapped the second and third arguments.
EDIT: fill and fill_n will work on anything that provides or can be treated as an output iterator. For standard containers like vector you can either pre-size the container or use back_inserter while for arrays you can use the form I indicated.
memset(sum,sizeof(sum),0);
Wrong.
I think you wanted to write:
memset(sum,0, sizeof(sum));
The signature of memset function is this:
void * memset ( void * ptr, int value, size_t num );
And its description is :
Sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char).
I think you have the parameters in the wrong order.
According to cplusplus.com, the size parameter should be last:
void * memset ( void * ptr, int value, size_t num );
The syntax of function memset is:
void *memset(void *s, int c, size_t n);
The memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c.
So you need:
memset (sum, 0, sizeof(sum));