GMP, C language memory allocation and pointer - c++

I was trying to code something like this
....
mpz_class *x = NULL;
mpz_class *lValue = NULL;
....
for(int k = 0; k < 2; k++) {
x = NULL;
lValue = NULL;
x = (mpz_class*) malloc(sizeof(mpz_class) * exponentForFactors[k]);
lValue = (mpz_class*) malloc(sizeof(mpz_class) * exponentForFactors[k]);
rValue = 0;
mpz_class exp = (p-1)/q[k];
mpz_powm(lValue[0].get_mpz_t(), B.get_mpz_t(),exp.get_mpz_t(), p.get_mpz_t()); <- this part
exponentForFactors[k] = {3, 1}
this code will loop twice as k is less than 2.
At first loop, it is ok. there is no error but when it is the second loop, it has this error message where I pointed. malloc: *** error for object 0x6000000000000000: pointer being realloc'd was not allocated
*** set a breakpoint in malloc_error_break to debug
I do not understand why this thing takes place only at the second loop?
Any suggestion would be grateful. Thanks.
////////////////////////////
even this code(when the second loop)
cout << "lvalue = " << lValue[0] << endl;
has the problem.

Since mpz_class is a class, and you are clearly coding in C++ (not C, I have changed your language tag accordingly), using the C allocator is improper. You should instead use new[] or better yet, use std::vector<> to allocate your array. Although you have allocated memory for your arrays, the objects within them are uninitialized, because their constructors have not been called.

Related

luaT_pushudata returns proper Tensor type and dimension, but garbage data

I have a short clip of C++ code that should theoretically work to create and return a torch.IntTensor object, but when I call it from Torch I get garbage data.
Here is my code (note this snippet leaves out the function registering, but suffice it to say that it registers fine--I can provide it if necessary):
static int ltest(lua_State* L)
{
std::vector<int> matches;
for (int i = 0; i < 10; i++)
{
matches.push_back(i);
}
performMatching(dist, matches, ratio_threshold);
THIntStorage* storage = THIntStorage_newWithData(&matches[0], matches.size());
THIntTensor* tensorMatches = THIntTensor_newWithStorage1d(storage, 0, matches.size(), 1);
// Push result to Lua stack
luaT_pushudata(L, (void*)tensorMatches, "torch.IntTensor");
return 1;
}
When I call this from Lua, I should get a [torch.IntTensor of size 10] and I do. However, the data appears to be either memory addresses or junk:
29677072
0
16712197
3
0
0
29677328
0
4387616
0
[torch.IntTensor of size 10]
It should have been the numbers [0,9].
Where am I going wrong?
For the record, when I test it in C++
for (int i = 0; i < storage->size; i++)
std::cout << *(storage->data+i) << std::endl;
prints the proper values.
As does
for (int i = 0; i < tensorMatches->storage->size; i++)
std::cout << *(tensorMatches->storage->data+i) << std::endl;
so it seems clear to me that the problem lies in the exchange between C++ and Lua.
So I got an answer elsewhere--the Google group for Torch7--but I'll copy and paste it here for anyone who may need it.
From user #alban desmaison:
Your problem is actually memory management.
When your C++ function return, you vector<int> is free, and so is its content.
From that point onward, the tensor is pointing to free memory and when you access it, you access freed memory.
You will have to either:
Allocate memory on the heap with malloc (as an array of ints) and use THIntStorage_newWithData as you currently do (the pointer that you give to newWithData will be freeed when it is not used anymore by Torch).
Use a vector<int> the way you currently do but create a new Tensor with a given size with THIntTensor_newWithSize1d(matches.size()) and then copy the content of the vector into the tensor.
For the record, I couldn't get it to work with malloc but the copying memory approach worked just fine.

C++ - CORBA::LongSeq to long*

I'm new to C++ (I usually work on Java), and I'm trying to convert a ::CORBA::LongSeq object to a long * in C++, in order to perform operations on it afterwards.
So basically, what I tried is to do that :
long * Sample (const ::CORBA::LongSeq& lKeys) {
long nbElts = lKeys.length();
long * lCles = NULL;
for(int iIndex = 0; iIndex < nbElts; iIndex++) {
lCles[iIndex] = (long) lFCKey[iIndex];
}
return lCles;
}
And what happens is that I can retrieve the length of lKeys (so it should be looking at the right location, as far as I can tell), but then I get an access violation exception when I enter inside the for loop.
0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF
I'm not sure of what I'm doing wrong though... Anyone has an idea ?
Here is one solution, and you don't get into the mess with pointers:
#include <vector>
std::vector<long> Sample (const ::CORBA::LongSeq& lKeys)
{
long nbElts = lKeys.length();
std::vector<long> lCles(nbElts);
for(int iIndex = 0; iIndex < nbElts; ++iIndex)
lCles[iIndex] = (long) lFCKey[iIndex];
return lCles;
}
This is guaranteed to work correctly, if the number of elements is correct.
Since you say you know Java, then a std::vector<long> would be the equivalent to a few of the Java containers that store sequences of values. For example, you can get the return value and call the vector's data() function to get you a long * that points to the vector's internal buffer.
But overall, get out of the pointer business (or try to limit their usage).
Edit: The comment stated to use CORBA::Long. So here it is:
std::vector<CORBA::Long> Sample (const ::CORBA::LongSeq& lKeys)
{
long nbElts = lKeys.length();
std::vector<CORBA::Long> lCles(nbElts);
for(int iIndex = 0; iIndex < nbElts; ++iIndex)
lCles[iIndex] = lFCKey[iIndex];
return lCles;
}
The difference between Java and C++ is that you have to manage your memory yourself (in most cases).
The error you get is that you try to assign things to an uninitialized variable (lCles), and returning a local variable. The local variable lCles which is stored on the stack will be "destroyed" once you leave the method.
One suggestion of how to do this could be something like this:
long* lCles = new long[lKeys.length()];
for(int iIndex = 0; iIndex < nbElts; iIndex++) {
lCles[iIndex] = (long) lFCKey[iIndex];
}
return lCles;
The important part in the method calling this code is to then release the memory held by this lCles by doing a
delete [] lCles; // or whatever the name of the variable is.
when done.
Like this:
long * l = Sample(lkeys);
// Do your stuff here
delete [] l;
(Using std::vector as suggested in another answer is actually preferred, since you don't have to do memory management by yourself.)
There are two things wrong here.
1) You attempt to use lCles before you have initialised it:
long * lCles = NULL;
..
lCles[iIndex]
This causes the access violation inside the for loop.
2) You return a pointer, lCles which is only declared locally:
return lCles;
This means that it goes out of scope when the function exits, and it then becomes invalid.

Undetected error with new operator

I was messing around trying to understand pointers and the operator "new"
and I ended up getting even more confused on what these 2 codes should result to, which is other but its not, so I wanted to understand what happened here.
thanks in advance.
#include <iostream>
using namespace std;
int main()
{
int * p = new int(50);
p[1] = 33;
cout << *p << endl;
}
Output: 50
and when I tried this
#include <iostream>
using namespace std;
int main()
{
int * p = new int[50];
p[1] = 33;
cout << *p << endl;
}
Output: -842150451
I was wondering about the meaning of each result.
In the first case
int * p = new int(50); // allocates 1 int on heap, initialized to value of 50
p[ 1] = 33; // p gives you the address of integer,
// p[1] moves the p pointer forward and accessing
// the pointed object results in undefined behavior,
// this means that at this moment anything can happen
// exception, crash, home war, nothing, everything,
// printing garbage value as well
In the second case:
int* p = new int[50]; // allocates 50 ints on heap, uninitialized
p[ 1] = 17; // initializes element with index 1 to value of 17
std::cout << *p; // p gives you the address of first element, with index 0
// which is still uninitialized, thus prints garbages
You should use
int* p = new int[50]();
to value-initialize ints to 0.
In the first one, you created dynamically a single int with a value of 50. When you try to assign the value 33, you actually assign it in memory that is not yours. It is undefined behaviour. But when you print it, you print the original value you made, which was 50.
In the second one, you created dynamically an array of 50 int. You've then specified the second value of in the array should be 33.* So when you print the value with cout << *p << endl;, you end up printing only the first value, which is undefined. Try it again, you'll probably get another value.
*Edit: as pointed in the comments, I should have been more explicit about this. An array starts at 0. So if you want to access the first value p[0] would do it.
In the first case you're creating an array of 50 ints, assigning a value to the SECOND int in the array, and then printing the first element in the array. Array indices start at 0, so when you dereference the pointer in your cout statement, it's printing whatever happened to be in memory at index 0.
In the second case you're creating a single integer, and initializing it with the value 50. When you dereference the pointer in the print statement, you're getting the integer you just created. The p[1] = 33 may or may not cause an error as your accessing unassigned memory.
int* p = new int[50];
allocates an array of int on the heap with 50 uninitialized elements, ranging from index 0 to 49.
Setting p[1] to 33 doesn't change p[0] which is what you're printing with "cout << *p".
The value -842150451 (0xCDCDCDCD in hex) is a magic number "Used by Microsoft's C++ debugging runtime library to mark uninitialised heap memory", see this question on SO.
int* p = new int(50);
allocates exactly one int on the heap and initializes it with the value 50, so setting p[1] afterwards should result in undefined behavior since you didn't allocate that memory where p[1] is referring to.
I'd recommend to use the Visual Studio Memory Windows to see what happens to the memory you're allocating while stepping through your code.

Casting pointer to Array (int* to int[2])

How do I cast or convert an int* into an int[x]?
First, I know that pointers can be indexed. So I know that I can loop through the pointer and array and manually convert the pointer. (eg. a for loop with arr[i] = p[i]). I want to know if the same result can be achieved in fewer lines of code.
As an example I tried to cast pointer int* c = new int[x] to an array int b[2]
int a = 1;
int b[2] = { 2, 3 };
int* c = new int[b[1]];
c[0] = b[0];
c[1] = b[1];
c[2] = a;
I wanted to see what values were where, so I made a simple program to output addresses and values. The output is just below:
Address of {type: int} &a = 0031FEF4; a = 1
Address of {type: int[2]} &b = 0031FEE4; b = 0031FEE4
Address of {type: int[2]} &b[0] = 0031FEE4; b[0] = 2
Address of {type: int[2]} &b[1] = 0031FEE8; b[1] = 3
Address of {type: int*} &c = 0031FED8; c = 008428C8
Address of {type: int*} &c[0] = 008428C8; c[0] = 2
Address of {type: int*} &c[2] = 008428D0; c[2] = 1
Once I made sure I knew what was where I tried a few things. The first idea that came to mind was to get the address of the second element to the pointer's allocation, then replace the array's memory address with it (see the code just below). Everything I did try ultimately failed, usually with syntax errors.
This is what I tried. I really want this to work, since it would be the simplest solution.
b = &c[1];
This did not work obviously.
Edit: Solution:
Don't do it!
If it's necessary create a pointer to an array and then point to the array; this is pointless for any purposes I can fathom.
For more detailed information see the answer by rodrigo below.
First of all b is an array, not a pointer, so it is not assignable.
Also, you cannot cast anything to an array type. You can, however, cast to pointer-to-array.
Note that in C and C++ pointer-to-arrays are rather uncommon. It is almost always better to use plain pointers, or pointer-to-pointers and avoid pointer-to-arrays.
Anyway, what you ask can be done, more or less:
int (*c)[2] = (int(*)[2])new int[2];
But a typedef will make it easier:
typedef int ai[2];
ai *c = (ai*)new int[2];
And to be safe, the delete should be done using the original type:
delete [](int*)c;
Which is nice if you do it just for fun. For real life, it is usually better to use std::vector.
Though you can't reassign an array identifier.. sometimes the spirit of what you're doing allows you to simply create a reference and masquerade yourself as an array. Note: this is just a slight extension of rodrigo's answer... and it is still worth mentioning that there is probably a better way to accomplish whatever the task is.
#include <iostream>
int main() {
int x[1000] = {0};
for(int i = 0; i < 10; ++i) {
int (&sub_x)[100] = *(int(*)[100])(&x[i*100]);
//going right to left basically:
// 1. x[i*100] -- we take an element of x
// 2. &x[N] -- we take the address
// 3. (int(*)[100]) -- we cast it to a pointer to int[100]
// 4. *(...) -- lastly we dereference the pointer to get an lvalue
// 5. int (&sub_x)[100] -- we create the reference `sub_x` of type int[100]
for(int j = 0; j < 100; ++j) {
sub_x[j] = (i*100)+j;
}
}
for(int i = 0; i < 1000; ++i) {
if(i != 0) {
std::cout << ", ";
}
std::cout << x[i];
}
std::cout << std::endl;
}
As you'd expect the output just ends up printing 0-999 with no gaps
output:
0, 1, 2, ..., 999

2d boolean array initialization in c++

I don't use C that much and I recently got confused about 2d array initialization problem. I need to debug somebody's code and stuck in the following(her original code):
const int location_num = 10000;
bool **location_matrix;
if (node_locations)
{
location_matrix = (bool **)malloc(location_num*sizeof(bool *));
if (!location_matrix)
{
cout<<"error 1 allocating location_matrix" << endl;
exit;
}
for (i=0; i<location_num; i++)
{
location_matrix[i] = (bool *) malloc(location_num*sizeof(bool ));
if (!location_matrix[i])
{
cout<<"error 2 allocating location_matrix" << endl;
exit;
}
for (j=0; j<location_num; j++)
location_matrix[i][j] = false;
}
}
I thought is was redundant, so I changed it to the following:
location_matrix[location_num][location_num] = { {false} };
However, segmentation fault happens at runtime.
My question is: how does the above code fail? If it looks right, what's the difference between dynamically allocation and static allocation? Is it just because the dimension might not be constant, so we need to do it dynamically?
Also, just for curiosity, how do I malloc 2d array that stores pointers? Thanks.
The change would likely require about 100MB (10,000 * 10,000 * 1) on the stack, so the segmentation fault was likely due to a stack overflow.
Edit I originally stated 400MB in the answer, but #Mooing Duck points out bool will likely be 1 byte. I was thinking the Win32 BOOL (for no real reason at all), which is typedefed to an int.
I actually don't see anything wrong with the code.
The following code doesn't work because location_matrix is not allocated:
location_matrix[location_num][location_num] = { {false} };
GCC will allow the following (as an extension):
bool location_matrix[location_num][location_num] = { {false} };
But it will blow your stack because 10000 x 10000 is too large.
Currently, your code uses dynamic allocation. That's the correct way to do it because the matrix is too large to be done as a static array (and may overrun the stack).
As for your last question, "how to make a 2d array that stores pointers": It can be done almost the same way as your current code. Just change bool to int*.
So a 2D array of NULL int pointers will look like this:
int ***location_matrix;
if (node_locations)
{
location_matrix = (int***)malloc(location_num*sizeof(int**));
if (!location_matrix)
{
cout<<"error 1 allocating location_matrix" << endl;
exit;
}
for (i=0; i<location_num; i++)
{
location_matrix[i] = (int**) malloc(location_num*sizeof(int*));
if (!location_matrix[i])
{
cout<<"error 2 allocating location_matrix" << endl;
exit;
}
for (j=0; j<location_num; j++)
location_matrix[i][j] = NULL;
}
}
The standard library is your friend.
#include <vector>
int
main()
{
int location_num = 1000;
std::vector<std::vector<bool> > location_matrix(location_num, std::vector<bool>(location_num, false));
}
Second, the array is likely too large to fit on the stack, so you'd need to dynamically allocate it -- but you can simplify the code as long as the difference between a 2-dimensional array and an array of pointers won't be an issue (as it would be if you needed to pass the array to a function or use pointer arithmetic with it).
You could use something like this:
bool (*location_matrix)[location_num];
location_matrix = (bool (*)[location_num])calloc( location_num,
location_num * sizeof(bool) );
...which allocates space for the whole two-dimensional array and gives a pointer to an array of bool arrays with location_num elements each.