Zero out a section of a multidimensional array - c++

I have a multidimensional array (a representation of a matrix). I need to zero out, not the entire array, but a section of it. What's the best method of doing this? I tried using memset, but it just gives me a typecast error.
Example
_matrix[row][column] = memset(
_matrix[row][column],
0,
sizeof(_matrix[row][column])
);
Declaration
float** _matrix = new float*[NUM_ROWS][NUM_COL];

The first parameter to memset() is the address of the location to zero. So:
memset(&_matrix[row][column], ...)
However, in your case the following would be far more straightforward:
_matrix[row][column] = 0.0;

This is tagged as C++ yet you're not really doing any C++. Why not just do that? Avoid all the lower level memset and direct array nonsense.
I certainly think you should take some of the previous advice and really learn the underlying C, memory access, etc., but in C++ this could simply be avoided.
A quick line of code to get you on your way:
typedef std::vector<std::vector<int> > Array2D;

Related

3D pointer seg error

I want to stick 2D arrays in a 3D array together, first i defined the 3D array in the following way
int ***grid;
grid=new int **[number];
then I want to assign the 2D arrays to the 3D construct
for(i=0;i<number;i++)
grid[i]=rk4tillimpact2dens(...);
with
int** rk4tillimpact2dens(...
...
static int** grid;
grid=new int*[600];
for(i=0;i<600;i++)
grid[i]=new int[600];
memset(grid,0x0,sizeof(grid));
...
return(grid);
}
so far no problem, everything works fine, but when I want to access the 3D array afterwards I get a seg fault. Like that e.g.
printf("%d",grid[1][1][1]);
What is my mistake?
Best,
Hannes
Oh, sorry, it was typo in my question, I did
printf("%d",grid[1][1][1]);
it's not working :(. But even
printf("%d",&grid[1][1][1]);
or
printf("%d",*grid[1][1][1]);
would not work. The strange thing is, that there are no errors unless I try to access the array
First, you discard the very first row of each matrix with that memset (the actual row is leaked). While technically grid[1][1][1] should still be readable, it probably becomes corrupt in some other place.
Can you provide a minimal verifiable example? This is likely to solve your problem.
To clear out the memory allocated for grid, you can't do the whole NxN matrix with one memset, it isn't contiguous memory. Since each row is allocated as a separate memory block, you need to clear them individually.
for(i=0;i<600;i++) {
grid[i]=new int[600];
memset(grid[i], 0, sizeof(int) * 600);
}
The 600 value should be a named constant, and not a hardcoded number.
And grid does not need to be a static variable.
Printing out the address
printf("%p",&grid[1][1][1]);
You are printing the address here. That's why you may not get what you desire to see.
printf("%d",grid[1][1][1]);
This will print the array element.
And to read an input from stdin you will use scanf() which requires you to pass address of an variable.
scanf("%d",&grid[1][1][1]);
Zeroing out the allocated memory
Also you can't get the size of the array using sizeof. SO to initialize with 0 you use memset on the chunks that are allocated at once with a new.
In your case example would be Like 1201ProgramAlarm pointed out
for(int i = 0; i < 600; i++){
...
memset(grid[i],0,sizeof(int)*600);
}
There is another way you can initialise an allocated memory in c++.
grid[i]=new int[600]();
For example:
int** rk4tillimpact2dens(...
...
static int** grid;
grid=new int*[600];
for(i=0;i<600;i++)
grid[i]=new int[600]();
...
return(grid);
}
Do you expect memset(grid,0x0,sizeof(grid)); not to zero the pointer values you've just assigned to grid[0] through to grid[599]? If so, you should test that theory by inspecting the pointer values of grid[0] through to grid[599] before and after that call to memset, to find out what memset does to true (more on that later) arrays.
Your program is dereferencing a null pointer which results directly from that line of code. Typically, a crash can be expected when you attempt to dereference a null pointer, because null pointers don't reference any objects. This explains your observation of a crash, and your observation of the crash disappearing when you comment out that call to memset. You can't expect good things to happen if you try to use the value of something which isn't an object, such as grid[1][... where grid[1] is a pointer consisting entirely of zero bits.
The term 3D array doesn't mean what you think it means, by the way. Arrays in C and C++ are considered to be a single allocation, where-as what your code is producing seems to be multiple allocations, associated in a hierarchical form; you've allocated a tree as opposed to an array, and memset isn't appropriate to zero a tree. Perhaps your experiments could be better guided from this point on by a book regarding algorithms, such as Algorithms in C, parts 1-4 by Robert Sedgewick.
For the meantime, in C, the following will get you a pointer to a 2D array which you can mostly use as though it's a 3D array:
void *make_grid(size_t x, size_t y, size_t z) {
int (*grid)[y][z] = malloc(x * sizeof *grid);
/* XXX: use `grid` as though it's a 3D array here.
* i.e. grid[0][1][2] = 42;
*/
return grid;
}
Assuming make_grid returns something non-null, you can use a single call to memset to zero the entirety of the array pointed to by that function because there's a single call to malloc matching that a single call to memset... Otherwise, if you want to zero a tree, you'll probably want to call memset n times for n items.
In C++, I don't think you'll find many who discourage the use of std::vector in place of arrays. You might want to at least consider that option, as well as the other options you have (such as trees; it seems like you want to use a tree, which is fine because trees have perfectly appropriate usecases that arrays aren't valid for, and you haven't given us enough context to tell which would be most appropriate for you).

two short questions about pointers and references

consider this code:
double *pi;
double j;
pi = &j;
pi[3] = 5;
I don't understand how is that possible that I can perform the last line here.
I set pi to the reference of j, which is a double variable, and not a double [] variable. so how is this possible that I can perform an array commands on it?
consider this code:
char *c = "abcdefg";
std::cout << &(c[3]) << endl;
the output is "defg". I expected that I will get a reference output because I used &, but instead I got the value of the char * from the cell position to the end. why is that?
You have two separate questions here.
A pointer is sometimes used to point to an array or buffer in memory. Therefore it supports the [] syntax. In this case, using pi[x] where x is not 0 is invalid as you are not pointing to an array or buffer.
Streams have an overload for char pointers to treat them as a C-style string, and not output their address. That is what is happening in your second case. Try std::cout << static_cast<const void *>(&(c[3])) << endl;
Pointers and arrays go hand in hand in C (sort of...)
pi[3] is the same as *(pi + 3). In your code however this leads to Undefined Behavior as you create a pointer outside an object bounds.
Also be careful as * and & are different operators depending on in which kind of expression the appear.
That is undefined behavior. C++ allows you to do things you ought not to.
There are special rules for char*, because it is often used as the beginning of a string. If pass a char* to cout, it will print whatever that points to as characters, and stop when it reaches a '\0'.
Ok, so a few main things here:
A pointer is what it is, it points to a location in the memory. So therefore, a pointer can be an array if you whish.
If you are working with pointers (dangerous at times), this complicates things. You are writing on p, which is a pointer to a memory location. So, even though you have not allocated the memory, you can access the memory as an array and write it. But this gives us the question you are asking. How can this be? well, the simple answer is that you are accessing a zone of memory where the variable you have created has absolutely no control, so you could possibly be stepping on another variable (if you have others) or simply just writting on memory that has not been used yet.
I dont't understand what you are asking in the second question, maybe you could explain a little more? Thanks.
The last line of this code...
double *pi;
double j;
pi = &j;
pi[3] = 5;
... is the syntactic equivalent to (pi + 3) = 5. There is no difference in how a compiler views a double[] variable and a double variable.
Although the above code will compile, it will cause a memory error. Here is safe code that illustrates the same concepts...
double *pi = new double[5]; // allocate 5 places of int in heap
double j;
pi[3] = 5; // give 4th place a value of 5
delete pi; // erase allocated memory
pi = &j; // now get pi to point to a different memory location
I don't understand how is that possible that I can perform the last
line here. I set pi to the reference of j
Actually, you're setting your pointer pi, to point to the memory address of j.
When you do pi[3], you're using a non-array variable as an array. While valid c++, it is inherently dangerous. You run the risk of overwriting the memory of other variables, or even access memory outside your process, which will result in the operating system killing your program.
When that's said, pi[3] means you're saying "give me the slot third down from the memory location of pi". So you're not touching pi itself, but an offset.
If you want to use arrays, declare them as such:
double pi[5]; //This means 5 doubles arrayed aside each other, hence the term "array".
Appropos arrays, in c++ it's usually better to not use raw arrays, instead use vectors(there are other types of containers):
vector<double> container;
container.push(5.25); //"push" means you add a variable to the vector.
Unlike raw arrays, a container such as a vector, will keep it's size internally, so if you've put 5 doubles in it, you can call container.size(), which will return 5. Useful in for loops and the like.
About your second question, you're effectively returning a reference to a substring of your "abcdefg" string.
&([3]) means "give me a string, starting from the d". Since c-style strings(which is what char* is called) add an extra NULL at the end, any piece of code that takes these as arguments(such as cout) will keep reading memory until they stumble upon the NULL(aka a 0). The NULL terminates the string, meaning it marks the end of the data.
Appropos, c-style strings are the only datatype that behaves like an array, without actually being one. This also means they are dangerous. Personally I've never had any need to use one. I recommend using modern strings instead. These newer, c++ specific variables are both safe to use, as well as easier to use. Like vectors, they are containers, they keep track of their size, and they resize automatically. Observe:
string test = "abcdefg";
cout<<test.size()<<endl;//prints 7, the number of characters in the array.
test.append("hijklmno");//appends the string, AND updates the size, so subsequent calls will now return 15.

Pascal and Delphi Arrays to C/C++ Arrays

In pascal and delphi, arrays have their lengths stored at some offset in memory from the array's pointer. I found that the following code works for me and it gets the length of an array:
type PInt = ^Integer; //pointer to integer.
Function Length(Arr: PInt): Integer;
var
Ptr: PInt;
Begin
Ptr := Arr - sizeof(Integer);
Result := Ptr^ + 1;
End;
Function High(Arr: PInt): Integer; //equivalent to length - 1.
Begin
Result := (Arr - sizeof(Integer))^;
End;
I translated the above code into C++ and it thus becomes:
int Length(int* Arr)
{
int* Ptr = (Arr - sizeof(int));
return *reinterpret_cast<char*>(Ptr) + 1;
}
int High(int* Arr)
{
return *(Arr - sizeof(int));
}
Now assuming the above are equivalent to the Pascal/Delphi versions, how can I write a struct to represent a Pascal Array?
In other words, how can I write a struct such that the following is true:
Length(SomeStructPointer) = SomeStructPointer->size
I tried the following:
typedef struct
{
unsigned size;
int* IntArray;
} PSArray;
int main()
{
PSArray ps;
ps.IntArray = new int[100];
ps.size = 100;
std::cout<<Length((int*) &ps); //should print 100 or the size member but it doesn't.
delete[] ps.IntArray;
}
In Pascal and Delphi, arrays have their lengths stored at
some offset in memory from the array's pointer.
This is not so. The entire premise of your question is wrong. The Delphi functions you present do not work in general. They might work for dynamic arrays. But it is certainly not the case that you can pass an pointer to an array and be sure that the length is stored before it.
And in fact the Delphi code in the question does not even work for dynamic arrays. Your pointer arithmetic is all wrong. You read a value 16 bytes to the left rather than 4 bytes. And you fail to check for nil. So it's all a bit of a disaster really.
Moving on to your C++ code, you are reaping the result of this false premise. You've allocated an array. There's no reason to believe that the int to the left of the array holds the length. Your C++ code is also very broken. But there's little point attempting to fix it because it can never be fixed. The functions you define cannot be implemented. It is simply not the case that an array is stored adjacent to a variable containing the length.
What you are looking for in your C++ code is std::vector. That offers first class support for obtaining the length of the container. Do not re-invent the wheel.
If interop is your goal, then you need to use valid interop types. And Delphi managed dynamic arrays do not qualify. Use a pointer to an array, and a separately passed length.
Why? I can see no good reason to do this. Use idiomatic Pascal in Pascal, use idiomatic C++ in C++. Using sizeof like that also ignores padding, and so your results may vary from platform to platform.
If you want a size, store it in the struct. If you want a non-member length function, just write one that works with the way you wrote the struct. Personally, I suggest using std::array if the size won't change and std::vector if it will. If you absolutely need a non-member length function, try this:
template<typename T>
auto length(const T& t) -> decltype(t.size()) {
return t.size();
}
That will work with both std::array and std::vector.
PS: If you're doing this for "performance reasons", please profile your code and prove that there is a bottleneck before doing something that will become a maintenance hazard.

Defining Array C/C++

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;
}

Accessing array beyond the limit

I have two character array of size 100 (char array1[100], char array2[100]). Now i just want to check whether anybody is accessing array beyond the limit or not. Its necessary because suppose allocated memory for array1 and array2 are consecutive means as the array1 finish then array2 starts. Now if anyone write: array1[101], conceptually its wrong but compiler will give warning but will not crash. So How can i detect this problems and solve it?
Update 1:
I already have a code of line 15,000. And for that code i have to check this condition and i can invoke my functions but cannot change the written code. Please suggest me according to this.
Most modern languages will detect this and prevent it from happening. C and its derivatives don't detect this, and basically can't detect this, because of the numerous ways you can access the memory, including bare pointers. If you can restrict the way you access the memory, then you can possibly use a function or something to check your access.
My initial response to this would be to wrap the access to these arrays in a function or method and send the index as a parameter. If the index is out of bounds, raise an exception or report the error in some other way.
EDIT:
This is of course a run-time prevention. Don't know how you would check this at compile time if the compiler cannot checkt this for you. Also, as Kolky has already pointed out, it'd be easier to answer this if we know which language you are using.
If you are using C++ rather than C there any reason you can't use std::vector? That will give you bounds checking if the user goes outside your range. Am I missing something here?
Wouldn't it be sensible to prevent the user having direct access to the collections in the first place?
If you use boost::array or similar you will get an exception range_error if array bounds are overstepped. http://www.boost.org/doc/libs/1_44_0/doc/html/boost/array.html. Boost is fabulous.
In C/C++, there is no general solution. You can't do it at compile time since there are too many ways to change memory in C. Example:
char * ptr = &array2;
ptr = foo(ptr); // ptr --;
ptr now contains a valid address but the address is outside of array2. This can be a bug or what you want. C can't know (there is no way to say "I want it so" in C), so the compiler can't check it. Sililarily:
char * array2 = malloc(100);
How should the C compiler know that you are treating the memory as a char array and would like a warning when you write &array2[100]?
Therefore, most solutions use "mungwalls", i.e. when you call malloc(), they will actually allocate 16/32 bytes more than you ask for:
malloc(size) {
mungwall_size = 16;
ptr = real_malloc(size + mungwall_size*2);
createMungwall(ptr, mungwall_size);
createMungwall(ptr+size, mungwall_size);
return ptr+size;
}
in free() it will check that 16 bytes before and after the allocated memory area haven't been touched (i.e. that the mungwall pattern is still intact). While not perfect, it makes your program crash earlier (and hopefully closer to the bug).
You could also use special CPU commands to check all memory accesses but this approach would make your program 100 to 1 million times slower than it is now.
Therefore, languages after C don't allow pointers which means "array" is a basic type which has a size. Now, you can check every array access with a simple compare.
If you want to write code in C which is save, you must emulate this. Create an array type, never use pointers or char * for strings. It means you must convert your data type all the time (because all library functions use const char * for strings) but it makes your code safer.
Languages do age. C is now 40 years old and our knowledge has moved on. It's still used in a lot of places but it shouldn't be the first choice anymore. The same applies (to a lesser extend) to C++ because it suffers from the same fundamental flaws of C (even though you now have libraries and frameworks which work around many of them).
If you're in C++ you can write a quick wrapper class.
template<typename T, int size> class my_array_wrapper {
T contents[size];
public:
T& operator[](int index) {
if (index >= size)
throw std::runtime_error("Attempted to access outside array bounds!");
if (index < 0)
throw std::runtime_error("Attempted to access outside array bounds!");
return contents[index];
}
const T& operator[](int index) const {
if (index >= size)
throw std::runtime_error("Attempted to access outside array bounds!");
if (index < 0)
throw std::runtime_error("Attempted to access outside array bounds!");
return contents[index];
}
operator T*() {
return contents;
}
operator const T*() const {
return contents;
}
};
my_array_wrapper<char, 100> array1;
array1[101]; // exception
Problem solved, although if you access through the pointer decay there will be no bounds checking. You could use the boost::array pre-provided solution.
If you ran a static analyser (i.e. cppcheck) against your code it would give you a bounds error
http://en.wikipedia.org/wiki/User:Exuwon/Cppcheck#Bounds_checking
to solve it... you'd be better off using a container of some sorts (i.e. std::vector) or writing a wrapper