Using vectors with GMP - c++

I'm trying to use vectors with GMP. But when I compile anything like this, I get "[...]\bits\vector.tcc [Error] array must be initialized with a brace-enclosed initializer". Any data structure with dynamic size works - a deque would be best but I had even more errors popping up when I tried that. How do I make this stop failing?
#include <vector>
#include <gmp.h>
int main(){
mpz_t test;
mpz_init(test);
std::vector<mpz_t> a_vector;
a_vector.push_back(test);
return 0;
}

Since GMP numbers are not directly assignable (in other words, you can't do mpz_t test = 0;' ormpz_t test1l; test1 = test;`, I don't believe they can be used in standard C++ container types.
If you want to do that, you may want to use the C++ interface for GMP instead:
https://gmplib.org/manual/C_002b_002b-Interface-General.html

Related

How does one pass an integer, to a pointer, to an std::array<double, integer>, while satisfying a constnt expression?

I have a function noise.cpp which is currently of the form,
double* noise(int* steps, ...)
//some code
std::array<double, *steps> NoiseOut;
//rest of code
Which is being tested and accessed by cppnoise.cpp,
#include <random>
#include <cmath>
#include<stdio.h>
#include <iostream>
#include "noise.h"
main(){
double* out;
int steps = 8;
int* ptr = &steps;
out = noise(ptr, 1, 1000, 0.1, 1, 3);
printf("TEST \n");
std::cout << out[0];
}
With header file,
extern double* noise(int*, double, double, double, double, double);
Previously I accessed the noise.cpp function through Python where the NoiseOut array was initially, double* NoiseOut = new double[steps]; with desirable results, but this method resulted in a memory leak.
Initially I tried deleting the allocated memory. But the function returns NoiseOut, so I am not sure if that's possible? So, instead I found out that the modern way is to use std::array as it comes with some form of garbage collection. If I tried to do,
double* noise(int steps, ...)
std::array<double, steps> NoiseOut;
I was told steps was not a constant expression. I tried every which way of constexpr, const, and static but, with no success. Usually with the same error error: ‘steps’ is not a constant expression. Also, the reason I pass a pointer from cppnoise.cpp to noise.cpp is because I read somewhere that the pointer is easier to work with, later in compile-time? Such that maybe I could convert it to a constant expression? Probably a fever dream.
So, how can I declare an integer value in a program, which I pass to a function, which is usable in an std::array without causing that error?
NOTE: I am very new to c++ and work primarily with SQL, Python, R, and SageMath.
std::array is ill suited for this because you don't know what size you need until the code runs. std::array needs to know the size when it is compiled.
Using new gives a dynamic array size at run time, which is why you could use it before.
If you are concerned about memory leaks (or actually, in general), then I suggest using an std::vector instead:
#include <vector>
//...
std::vector<double> NoiseOut;
NoiseOut.reserve(*steps);
An std::vector should allow you to do most everything an std::array or C Array would allow you to so, though I suggest reading up on its documentation (linked above). Note that std::vector also comes with its own garbage collection of sorts in the same way std::array does.

Converting String to Integer. Why this error? I want to change the ID (string) to IC (integer). Both are arrays. I'm still a beginner by the way

#include <iostream>
#include <stdlib.h>
#include <cstring>
using namespace std;
int main()
{
string ID[]={"620301025123"}; //ID array
long long int IC[10]={0}; //IC array
// loop to change the ID string to Array IC. I will want to increase the size
// of ID array, later on, to put in new data but for now, I'm just using one data
// which is "620301025123" first.
for(int i = 0; i < 10; ++i){
IC[i]= {atoll(ID[i].c_str())};
}
}
The error I got is:
14 29 C:\Users\ASUS\Desktop\Assign1\Untitled3.cpp [Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11*/
First of all: it's #include <cstdlib> in C++.
Then, your problem does not seem to be the conversion to long long, but the initialization of the string, at least that's what the warning (not an error) says. You are using extended initializer lists, which are C++11, but haven't activated C++11 support.
The warning tells you how to activate it.
And finally: Don't get in the habit of using using namespace, at least not globally. You can use using on specific symbols, but even this I'd only do locally, and never globally.

reference to an array of size determined at run-time

I tried to find this but can't find any. I know I can create a reference to an array variable:
int x[10] = {}; int (&y)[10] = x;
However, in the case that the array size is not known at compile time, like in the following code:
const int n = atoi( string ); //the string is read from a text file at run time.
int x[n] = {}; int (&y)[n] = x; //this generates a compiling error.
Even if int n is declared const, as long as n is not known at compile time, the reference is invalid. The compiler will say something like this: reference to type 'int [n]' cannot bind to a value of unrelated type 'int [n]'. Anyone has any idea about how to fix this? Thanks in advance.
Runtime-length arrays are a C99 feature and do not exist in standard C++. They're present as an extension on some C++ compilers, but don't mix well with C++ features, like references and templates.
You should probably use a vector.
The feature of declaring arrays dynamically like shouldn't be used in C++. Not all compilers support it. Consider using the STL containers instead. Like std::vector<int>

Using deque to insert unsigned char arrays

I want to push_back two dimensional char arrays into deque. The following did not work. How should defined m_message data variable in order push_back those data.
unsigned char message_data[2][1500]; //definition
func1(message_data[0]);
func1(message_data[1]);
std::deque<unsigned char*> m_messagedata;
m_messagedata.push_back(&message_data[0]);
m_messagedata.push_back(&message_data[1]);
You're pushing back pointers, not arrays. If those arrays die, your pointers dangle. You didn't tell us what your problem is, but this is likely to be it.
Also you seem to be declaring two arrays with the same name, with different bounds, one of which is illegal (0). I presume that this was a mistake with your question, rather than your original code: please post your real testcase next time.
Nowadays, C++ has a wrapper around what were previously uncopyable arrays, allowing them to be stored directly inside standard containers; that wrapper is called std::array. So, try:
#include <array>
#include <deque>
typedef std::array<unsigned char, 1500> ArrayType;
int main()
{
std::array<ArrayType, 2> message_data;
std::deque<ArrayType> q;
q.push_back(message_data[0]);
q.push_back(message_data[1]);
}
Note that the container now contains copies of the two inner arrays.
The other solutions are right but since you want your code to remain the same as far as possible maybe you could do this:
unsigned char message_data[2][1500]; //definition
//using CharArrPtr = unsigned char(*)[1500];
typedef unsigned char (*CharArrPtr)[1500];
std::deque<CharArrPtr> m_messagedata;
m_messagedata.push_back(&message_data[0]);
m_messagedata.push_back(&message_data[1]);
As was mentioned earlier what is being done here is pushing pointers to possibly local variables. So you will have to be sure that they remain valid when they are used.

Creating dynamic arrays without "new" in VC++

I want to create an array in Visual Studio as it is possible in C99:
int function(int N)
{
int x[N];
return 1;
};
But even VS2013 doesn't support this. Is there another way (except using new and delete) to create x without the need to fix N at translation time?
Thank you very much!
The condoned way of doing this in C++ is by using vectors
#include <vector>
int function(int N)
{
std::vector<int> x(N);
return 1;
};
If you know that N won't be enormous (and since you seem to want this memory on the stack, anyway), you can use _alloca, which is a C function. See the documentation here.
#include <malloc.h>
int function(int N)
{
int *x = _alloca(sizeof(int)*N);
return 1;
};
This isn't really recommended, and has been superceded by _malloca, which requires a call to _freea after you're done with the memory.
Note that both versions will free the memory when the function exits, but the first version will allocate memory on the heap, whereas the second will allocate on the stack (and therefore has a much stricter upper limit on N). Besides the convenience and low-overhead of the std::vector class, using C-style pointers in a C++ program is kind of a downer anyway. :)
In order for an array in C++ to be defined on the stack (i.e. without new), the size of it must be known at compile time, such as a const int or a preprocessor macro. As this is not the case in this situation, you can use the following instead:
#include <vector>
using namespace std;
// ...
int function(int n)
{
vector<int> x (n);
return 1;
}
There is no such a possibily to define a variable length array in the stack in C++. But you can use std::vector instead though it allocates memory in the heap.