How to use realloc in cpp - c++

I have following cpp code
#include <stdio.h> /*utiliser printf*/
#include <fcntl.h>
#include <math.h> /*utiliser pour les formules de math*/
#include <malloc.h>
#include <iostream.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
/* Le type nombre complexe */
typedef struct {
double Preel;
double Pimaginaire;
} COMPLEXE;
#define ALLOC_ERROR 1
void indienne(double *MatE, int tE, int nE, double *SortieExp, double *Tempbis)
{
double *TempE=NULL, *SortieE=NULL;
int *dec=NULL;
int i, tampon, kE;
kE=(int)(log(nE)/log(2));
if(nE==8)
kE=3;
/* ALLOCATION DES MATRICES*/
if (!(TempE = (double *)calloc(tE * tE, sizeof(double))))
exit(ALLOC_ERROR);
printf("check1 te=%d, nE=%d",tE,nE);
if (!(dec = (int *)realloc(kE , sizeof(int))))
exit(ALLOC_ERROR);
if (!(SortieE = (double *)calloc(tE * tE, sizeof(double))))
exit(ALLOC_ERROR);
printf("check2 te=%d",tE);
memcpy(TempE,MatE,tE * tE * sizeof(double));
for (i=0; i<tE; i++)
*(Tempbis+(tE * i) + i) = 1.0;
if (nE==1)
{
memcpy(SortieExp, MatE, tE*tE*sizeof(double));
}
else
{
printf("kE=%d, nE=%d\n", kE, nE);
if (nE%2==0)
decompose(kE, nE,dec);
else
decompose(kE, nE-1, dec);
for (i=0; i<kE; i++)
{
carre(TempE, tE, SortieE);
memcpy(TempE, SortieE, tE*tE*sizeof(double));
tampon=*(dec+i);
if (tampon==1)
{
mult(Tempbis, tE, tE, SortieE, tE, tE, SortieExp);
memcpy(Tempbis, SortieExp, tE*tE*sizeof(double));
}
}
if (nE%2 !=0)
{
memcpy(Tempbis, SortieExp, tE*tE*sizeof(double));
mult(Tempbis, tE, tE, MatE, tE, tE, SortieExp);
}
}
free(TempE);
free(SortieE);
free(dec);
}
When I compile this code following error occurres
invalid conversion from 'int' to 'void*' [-fpermissive]|
that is about following line of code
if (!(dec = (int *)realloc(kE , sizeof(int))))
How can I remove this error?

You are passing int kE as the first parameter here:
realloc(kE , sizeof(int))
However, realloc is declared like this:
void *realloc(void *ptr, size_t size);
In other words it expects a pointer! Please read the manual page I link to above to get more details. In short, you probably want something like this for the error line:
if (!(dec = (int *)realloc(dec , sizeof(int))))
Note that this is slightly bad, because if realloc fails, you lose the original value of dec, causing a memory leak. It doesn't really matter if you are going to exit on error, but otherwise you should keep the original value of dec, so you can handle error more gracefully than just exiting.
Another note, you really should use C++ container classes like vector instead of fooling around with C memory allocation functions.
There are probably other issues in your code, but this answer doesn't try to be code review, but just explain why you get the error you get.

Try without do it like this :
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *pa = malloc(10 * sizeof *pa); // allocate an array of 10 int
if(pa) {
printf("%zu bytes allocated. Storing ints: ", 10*sizeof(int));
for(int n = 0; n < 10; ++n)
printf("%d ", pa[n] = n);
}
int *pb = realloc(pa, 1000000 * sizeof *pb); // reallocate array to a larger size
if(pb) {
printf("\n%zu bytes allocated, first 10 ints are: ", 1000000*sizeof(int));
for(int n = 0; n < 10; ++n)
printf("%d ", pb[n]); // show the array
free(pb);
} else { // if realloc failed, the original pointer needs to be freed
free(pa);
}
}

Related

CUDA pointer inside kernel becomes null

I'm trying to pass a pointer to triangle data to a kernel, but when debugging I find the pointer becomes null, d_list contains the triangles and both d_list and d_world are members of the main window class, also the error checking returns "no error"
d_list is of type hittable* and d_world is hittable_list*
__global__ void create_world(hittable* d_list, hittable_list* d_world, int num_triangles) {
if (threadIdx.x == 0 && blockIdx.x == 0) {
// the class hittable_list contains a counter for the list size, which no matter the
// scene size it always becomes zero
d_world = new hittable_list(&d_list, num_triangles);
}
}
checkCudaErrors(cudaMalloc((void**)&d_list, num_hittables * sizeof(triangle)));
checkCudaErrors(cudaMalloc((void**)&d_world, sizeof(hittable_list)));
cudaMemcpy(d_list, m_triangles.data(), num_hittables * sizeof(triangle), cudaMemcpyHostToDevice);
create_world << <1, 1 >> > (d_list, d_world, num_hittables);
checkCudaErrors(cudaGetLastError());
checkCudaErrors(cudaDeviceSynchronize());
I tried initializing the "world" in the host then cudaMemcpy'ing to the d_world, but it also fails
EDIT: minimal exmple
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <vector>
struct make_list {
__device__ make_list(float** list, int n) { contents = list; size = n; };
float** contents;
int size;
};
__global__ void render(make_list** world) {
int size = (*world)->size; // set a breakpoint here, the size is 0
}
__global__ void create_world(float* d_list, make_list* d_world, int num_triangles) {
if (threadIdx.x == 0 && blockIdx.x == 0) {
// the class hittable_list contains a counter for the list size, which no matter the
// scene size it always becomes zero
d_world = new make_list(&d_list, num_triangles);
}
}
int main () {
float* d_list;
make_list* d_world;
int size = 8;
std::vector<float> m_triangles(size);
cudaMalloc((void**)&d_list, size * sizeof(float));
cudaMalloc((void**)&d_world, sizeof(make_list));
cudaMemcpy(d_list, m_triangles.data(), size * sizeof(float), cudaMemcpyHostToDevice);
create_world << <1, 1 >> > (d_list, d_world, size);
cudaDeviceSynchronize();
render << <1, 1 >> > (&d_world);
cudaDeviceSynchronize();
return 0;
}
EDIT 2: updated with virtual function call, it's causing crashes
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <vector>
#include <cstdio>
class hittable {
public:
__device__ virtual int hit() const = 0;
};
struct make_list : public hittable {
__device__ make_list(float** list, int n) { contents = list; size = n; };
__device__ virtual int hit() const {
return size;
}
float** contents;
int size;
};
__global__ void render(make_list** world) {
int size = (*world)->size; // set a breakpoint here, the size is 0
printf("size = %d\n", size);
int new_size = (*world)->hit();
printf("new size = %d\n", new_size);
}
__global__ void create_world(float* d_list, make_list** d_world, int num_triangles) {
if (threadIdx.x == 0 && blockIdx.x == 0) {
// the class hittable_list contains a counter for the list size, which no matter the
// scene size it always becomes zero
*d_world = new make_list(&d_list, num_triangles);
}
}
int main() {
float* d_list;
make_list** d_world;
cudaMalloc(&d_world, sizeof(make_list*));
int size = 8;
std::vector<float> m_triangles(size);
cudaMalloc((void**)&d_list, size * sizeof(float));
cudaMemcpy(d_list, m_triangles.data(), size * sizeof(float), cudaMemcpyHostToDevice);
create_world << <1, 1 >> > (d_list, d_world, size);
cudaDeviceSynchronize();
render << <1, 1 >> > (d_world);
cudaDeviceSynchronize();
return 0;
}
There are at least a few issues.
In C++, when you pass a variable to a function via the function parameters, a copy of that variable is made for local use by the function. Any modifications made to that variable will not show up globally, i.e. in the calling environment, because the function is operating on a copy of the variable. Therefore this could never do what you want:
d_world = new make_list(&d_list, num_triangles);
There is nothing illegal about it, per se, but it will not have the desired effect. The global copy of d_world is unchanged by that assignment. This is a C++ concept, not unique or specific to CUDA, and it trips people up from time to time.
This is almost never legal in CUDA:
render << <1, 1 >> > (&d_world);
^
In typical usage, it is not possible to pass the address of a host location to device code via a kernel call parameter. Any attempt to dereference that pointer &d_world will result in dereferencing the address of a host location. That is illegal in CUDA device code.
While not necessarily a problem at this point, you should be aware of the fact that in-kernel new operates against the device heap which has a default limit of 8MB, and furthermore allocations created this way cannot take part in host-issued cudaMemcpy* calls. These topics are covered in the programming guide.
When I make changes to address those first 2 items, I get what appear to be sensible results:
$ cat t2190.cu
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <vector>
#include <cstdio>
struct make_list {
__device__ make_list(float** list, int n) { contents = list; size = n; };
float** contents;
int size;
};
__global__ void render(make_list** world) {
int size = (*world)->size; // set a breakpoint here, the size is 0
printf("size = %d\n", size);
}
__global__ void create_world(float* d_list, make_list** d_world, int num_triangles) {
if (threadIdx.x == 0 && blockIdx.x == 0) {
// the class hittable_list contains a counter for the list size, which no matter the
// scene size it always becomes zero
*d_world = new make_list(&d_list, num_triangles);
}
}
int main () {
float* d_list;
make_list** d_world;
cudaMalloc(&d_world, sizeof(make_list*));
int size = 8;
std::vector<float> m_triangles(size);
cudaMalloc((void**)&d_list, size * sizeof(float));
cudaMemcpy(d_list, m_triangles.data(), size * sizeof(float), cudaMemcpyHostToDevice);
create_world << <1, 1 >> > (d_list, d_world, size);
cudaDeviceSynchronize();
render << <1, 1 >> > (d_world);
cudaDeviceSynchronize();
return 0;
}
$ nvcc -o t2190 t2190.cu
$ compute-sanitizer ./t2190
========= COMPUTE-SANITIZER
size = 8
========= ERROR SUMMARY: 0 errors
$
Although you don't show how you are using the contents member of the make_list object, I'm doubtful that this could possibly do anything useful for you, for the same reason as I have indicated in item 1 above:
*d_world = new make_list(&d_list,
^^^^^^^
The address you are using there is the address of a temporary local variable made by the function. My guess is you probably want d_list there or possibly *d_list, and this might necessitate changes in your contents object member of the handling of that object member. Whatever you are doing there will almost certainly require changes not unlike the refactoring I have done to address items 1 and 2.
For now, without knowing anything further about your intent, something that seems sensible to me would be like this:
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <vector>
#include <cstdio>
struct make_list {
__device__ make_list(float* list, int n) { contents = list; size = n; };
float* contents;
int size;
};
__global__ void render(make_list** world) {
int size = (*world)->size; // set a breakpoint here, the size is 0
printf("size = %d\n", size);
}
__global__ void create_world(float* d_list, make_list** d_world, int num_triangles) {
if (threadIdx.x == 0 && blockIdx.x == 0) {
// the class hittable_list contains a counter for the list size, which no matter the
// scene size it always becomes zero
*d_world = new make_list(d_list, num_triangles);
}
}
int main () {
float* d_list;
make_list** d_world;
cudaMalloc(&d_world, sizeof(make_list*));
int size = 8;
std::vector<float> m_triangles(size);
cudaMalloc((void**)&d_list, size * sizeof(float));
cudaMemcpy(d_list, m_triangles.data(), size * sizeof(float), cudaMemcpyHostToDevice);
create_world << <1, 1 >> > (d_list, d_world, size);
cudaDeviceSynchronize();
render << <1, 1 >> > (d_world);
cudaDeviceSynchronize();
return 0;
}

pthread_exit() throws warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] warning

I have been learning about pthread library, and have created a simple code to multiply two numbers, however I'm not able to get rid of this warning.
Ps. The code works fine.
#include <stdio.h>
#include <pthread.h>
struct numbers {
int num1,num2;
};
void *mult(void *param) {
struct numbers *data = param;
int res = data->num1 * data->num2;
pthread_exit((void *)res);
}
int main(){
pthread_t tid;
struct numbers n;
n.num1 = 2;
n.num2 = 3;
pthread_create(&tid, NULL,mult, (void*)&n);
int res;
pthread_join(tid, (void *)&res);
printf("%d\n",(int)res);
return 0;
}
Here's the warning:
1.c: In function ‘mult’:
1.c:12:17: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
12 | pthread_exit((void *)res);
Any insights would be highly appreciated.
change
pthread_exit((void *)res);
to
pthread_exit((void *)&res);

Segmentation fault when calling a class constructor

I'm trying to instantiate a class for a specific implementation of a symbol table and, following the instructions for the project, I'm doing it via a pointer. My constructor does a lot as it is the thing building the symbol table from a text file, but I'm getting a Segmentation fault error at the end of the constructor. What I don't understand is what exactly is giving me this error. I've done a bit of debugging and it seems my constructor is running just fine, as it gets to the breakpoint I put at the very last bracket and all the data is in the vector as I expected. When it tries to step out of the constructor and back to the main file, though, it gives me that error.
The main file is as follows:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string.h>
#include <time.h>
using namespace std;
#include "tabeladesimbolos.hpp"
typedef char * String;
typedef int * Integer;
int main(int argc, char *argv[])
{
fstream arqTexto;
/* abra arquivo com texto */
arqTexto.open(argv[1]);
if (arqTexto.fail())
{
cout << "ERRO: arquivo" << argv[1] << "nao pode ser aberto.\n";
exit(EXIT_FAILURE);
}
arqTexto.close();
string nome_arquivo = argv[1];
/* crie a ST*/
cout << "criando ST...\n";
/* usadas para medir tempo de processamento */
clock_t start, end;
double elapsed = 0;
start = clock();
vetorDes *st = new vetorDes(nome_arquivo);
end = clock();
/* calcule o tempo */
elapsed = ((double)(end - start)) / CLOCKS_PER_SEC;
cout << "arquivo lido e ST construida em " << elapsed << " segundos\n";
delete st;
return 0;
}
The error happens in the following line:
vetorDes *st = new vetorDes(nome_arquivo);
The file with the constructor (tabeladesimbolos.hpp) is:
#include <string>
#include <string.h>
#include <iostream>
#include <fstream>
#include <vector>
typedef char * String;
typedef int * Integer;
using namespace std;
struct Valor
{
String chave;
Integer valor;
};
class vetorDes
{
vector<Valor> vetor;
public:
vetorDes(string nomeArquivo);
void insere(String chave, Integer valor);
Integer devolve(String chave);
};
vetorDes::vetorDes(string nomeArquivo)
{
ifstream arqTexto;
String palavra;
Integer aux = nullptr;
vetor.reserve(10000);
arqTexto.open(nomeArquivo);
while (arqTexto >> palavra)
{
aux = devolve(palavra);
if (aux == nullptr)
{
int* um = new int;
*um = 1;
insere(palavra, um);
}
else
{
(*aux)++;
}
}
}
void vetorDes::insere(String chave, Integer valor)
{
Valor *aux = new Valor;
aux->chave = (String) malloc(20*sizeof(char));
strcpy(aux->chave, chave);
aux->valor = valor;
int maxsize = vetor.max_size();
int currentsize = vetor.size();
vetor.push_back(*aux);
return;
}
Integer vetorDes::devolve(String chave)
{
for (std::size_t i = 0; i < vetor.size(); ++i)
{
String teste = vetor[i].chave;
if (!strcasecmp(teste, chave))
{
return vetor[i].valor;
}
}
return nullptr;
}
My debugger gets me to that last } in the constructor without error, which leads me to believe the problem is with the way I allocate something as it only comes up when the program tries to finish the "new vetorDes" call.
The full error message is:
Program received signal SIGSEGV, Segmentation fault.
__GI___libc_free (mem=0x3b002e6f746e6174) at malloc.c:3103
What am I doing wrong? What am I missing?
String palavra;
...
while (arqTexto >> palavra)
I didn't see anything between declaring palavra, which is a pointer, and reading into it, that made palavara point anywhere. The pointer is uninitialized, so it points to some random place, and you are reading your data into that random place. Anything can happen then, except anything good.
__GI___libc_free (mem=0x3b002e6f746e6174)
The 0x3b002e6f746e6174 is obviously invalid pointer:
it's not in canonical form,
its tail looks like ASCII string tanto.
It is safe to assume that you have some kind of heap overflow (or other heap corruption). Use Valgrind or Address Sanitizer to find the bug.
As N.M. noted, you are doing yourself a great disservice by hiding pointers behind these typedefs:
typedef char * String;
typedef int * Integer;
The bug would be much more noticeable if you didn't:
char *palavra; // uninitialized pointer
...
while (arqTexto >> palavra) // BUG: writes to random memory

Error error: ‘void*’ is not a pointer-to-object type

Hello Guys I am facing a slight issue in a code
This program is supposed to calculate
( (a+b) x (c+d) ) / e
Create three threads, one for
Addition Only
Multiplication Only
Division
ONLY one thread should be created in main()
Display the results in division thread.
The int values(a, b, c, d, e) should be taken from the user in main and passed on the thread created in main. The other result of each step should be passed on the next step.
And this is the program that i wrote for above scenario
#include <iostream>
#include <pthread.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
void *Division(void *arg_div)
{
int result = arg_div[0]/arg_div[1];
cout << result ;
pthread_exit(NULL);
}
void *Multiplication(void *arg_mul)
{
int arg1[2];
arg1[0]=arg_mul[0]*arg_mul[1];
arg1[1]=arg_mul[2];
pthread_t div;
pthread_create(&div,NULL,Division,(void*)arg1);
pthread_join(div,NULL);
pthread_exit(NULL);
}
void *Addition(void *arg_add)
{
int arg[3];
arg[0]=arg_add[0]+arg_add[1];
arg[1]=arg_add[2]+arg_add[3];
arg[2]=arg_add[4];
pthread_t ad;
pthread_create(&ad,NULL,Multiplication,(void*)arg);
pthread_join(ad,NULL);
pthread_exit(NULL);
}
int main()
{
int values[5];
for(int i=0;i<5;i++)
{
cin >> values[i];
}
pthread_t pa;
pthread_create(&pa,NULL,Addition,(void*)values);
pthread_join(pa,NULL);
return 0;
}
Why did you change the pointer type (C-style...) to void*? (trick question to make you walk on the proper path).
Just get the int* back, they are pointers that you can dereference. void* are pointers, but you can't get a void object and even less do operations on it.
int* args = static_cast<int*>(arg);
arithmetic on void pointer is not allowed, you need to convert void * to target type here i.e. int*
after converting to void* to int*, your Addition() looks like below, you have to make same changes to all function to make it work.
void *Addition(void *arg_add)
{
int *input = (int *)arg_add;
int arg[3];
arg[0]=input[0]+input[1];
arg[1]=input[2]+input[3];
arg[2]=input[4];
}
You can't dereference a void* - you need to cast the thread functions' parameters back to int*.
For example,
void *Division(void *arg_div)
{
int* args = static_cast<int*>(arg_div);
int result = args[0]/args[1];
...
void * Division(void * arg_div) {
int * arg_div_int = (int * ) arg_div;
int result = arg_div_int[0] / arg_div_int[1];
...
}
void * Multiplication(void * arg_mul) {
int * arg_mul_int = (int * ) arg_mul;
int arg1[2];
arg1[0] = arg_mul_int[0] * arg_mul_int[1];
arg1[1] = arg_mul_int[2];
...
}
void * Addition(void * arg_add) {
int * arg_add_int = (int * ) arg_add;
int arg[3];
arg[0] = arg_add_int[0] + arg_add_int[1];
arg[1] = arg_add_int[2] + arg_add_int[3];
arg[2] = arg_add_int[4];
..
}
Here is a fix to your problem. You have to convert the void* to a int* and then use the values in the int array.

Why does reverse this function not work

In the constructor I fill the array on the device side.
but now I want to execute reverse function on the array.
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
__global__ void generateVector(int *data,int count){
int tid = blockIdx.x;
data[tid] = -tid;
}
__global__ void reverseArray(int *data,int count){
int tid = blockIdx.x;
data[tid] = tid;
}
class FData{
private:
int *data;
int size;
public:
FData(int sizeP){
size = sizeP;
data = new int[size];
int *devA;
cudaMalloc((void**) &devA, size * sizeof(int));
generateVector<<<size,1>>>(devA,size);
cudaMemcpy(data,devA, size * sizeof(int),cudaMemcpyDeviceToHost);
cudaFree(devA);
}
~FData(){
delete [] data;
}
int getSize(){
return size;
}
int elementAt(int i){
return data[i];
}
void reverse(){
int *devA;
cudaMalloc((void**) &devA, sizeof(int));
reverseArray<<<size,1>>>(devA,size);
cudaMemcpy(data,devA,size * sizeof(int),cudaMemcpyDeviceToHost);
cudaFree(devA);
}
};
int main(void) {
FData arr(30);
cout << arr.elementAt(1);
arr.reverse();
cout << arr.elementAt(1);
return 0;
}
It still prints the values which I filled in the constructor. What is the problem here? How can i solve it? What is going wrong?
Your kernels aren't reversing anything. They're just negating the values, so if anything I would be quite surprised if you saw anything get reversed. With that said, if you add error checking to your code (see this other SO post on how best to do the error checking) then you'll see that your code will fail on the call to cudaMalloc in your reverse function. You can fix this by changing devA to be a plain pointer (it doesn't really make sense for you to be allocating it as a host-array anyways, as you're not using it on the host to begin with).
void reverse(){
int *devA;
cudaMalloc((void**) &devA, size * sizeof(int));
reverseArray<<<size,1>>>(devA,size);
cudaMemcpy(data,devA,size * sizeof(int), cudaMemcpyDeviceToHost);
cudaFree(devA);
}
Also, you should free your memory too, you have both host-side and device-side memory leaks. Whenever you have a cudaMalloc call, you should havea corresponding cudaFree. Also, consider adding a destructor to free your host-side data member, as you have a memory leak there too.
~FData()
{
delete [] data;
}