Allocate memory dynamically of a vector of struct - c

I can't access my pointer by index notation in main function. The way I'm passing the pointer as paramter to the functions, is that right ? I tried without the & and It didnt work neither. Here is my code:
//My Struct
typedef struct{
int a;
double d;
char nome[20];
}contas;
//Function to allocate memory
void alloca_vetor(contas *acc, int linhas){
acc = malloc(linhas * sizeof(contas));
if(acc == NULL){
printf("ERRO AO ALOCAR MEMORIA\n");
exit(0);
}
printf("ALLOCATION SUCCESSFUL");
}
//Function to fill the vector
void fill_vetor(contas *acc, int linhas){
int i,a;
for(i=0; i< linhas; i++){
acc[i].a = i;
}
printf("FILL SUCCESSFUL !\n");
for(i=0; i< linhas; i++){
printf("%i\n", acc[i].a);
}
}
int main()
{
int i, num_linhas = 5;
contas *array;
alloca_vetor(&array, num_linhas);
fill_vetor(&array, num_linhas);
// ERROR HAPPENS HERE - Segmentation Fault
for(i=0; i < num_linhas; i++){
printf("%i\n", array[0].a);
}
free(array);
return 0;
}

Rewrite function alloca_vetor the following way
void alloca_vetor( contas **acc, int linhas ){
*acc = malloc(linhas * sizeof(contas));
if(*acc == NULL){
printf("ERRO AO ALOCAR MEMORIA\n");
exit(0);
}
printf("ALLOCATION SUCCESSFUL");
}
And call function fill_vetor like
fill_vetor(array, num_linhas);

Related

How to dynamically allocate vector and struct in a code?

I'm trying to allocate a struct and an array in the code below, but I have no idea how to proceed.
I'm trying to do this without adding other libraries.
It's in portuguese so I'm sorry if you don't understant the meaning.
struct RegistroAluno{
int Matricula;
char Nome[20];
int AnoNascimento;
};
int main()
{
int QuantidadeAlunos;
printf("Quantos alunos serão armazenados?\n");
scanf("%i", &QuantidadeAlunos);
struct RegistroAluno P1[QuantidadeAlunos];
struct *P1=(int *)malloc(QuantidadeAlunos*sizeof(struct));
for(int i=0; i<QuantidadeAlunos; i++){
printf("Qual a matrícula do aluno?\n");
scanf("%i", &P1[i].Matricula);
}/* I gotta do the same to all the other elements of the struct*/
return 0;
}
I'm trying to allocate a struct and an array
You allocate a variable length array (VLA) of struct RegistroAluno here:
struct RegistroAluno P1[QuantidadeAlunos];
Alternatively, you can allocate the array dynamically like this:
struct RegistroAluno *P1 = malloc(QuantidadeAlunos*sizeof(*P1));
Here the complete program with includes and error handling:
#include <stdlib.h>
#include <stdio.h>
struct RegistroAluno{
int Matricula;
char Nome[20];
int AnoNascimento;
};
int main(void) {
printf("Quantos alunos serão armazenados?\n");
int QuantidadeAlunos;
if(scanf("%i", &QuantidadeAlunos) != 1) {
printf("scanf failed\n");
return 1;
}
if(QuantidadeAlunos < 1) {
printf("QuantidadeAlunos must be > 0\n");
return 1;
}
struct RegistroAluno *P1 = malloc(QuantidadeAlunos*sizeof(*P1));
if(!P1) {
printf("malloc failed\n");
return 1;
}
for(int i=0; i<QuantidadeAlunos; i++){
printf("Qual a matrícula do aluno?\n");
if(scanf("%i", &P1[i].Matricula) != 1) {
printf("scanf failed\n");
return 1;
}
}
}
and example session:
Quantos alunos serão armazenados?
2
Qual a matrícula do aluno?
3
Qual a matrícula do aluno?
4

CSR and BFS always finds with 0 steps

I am trying to create a program that creates a graph in the CSR (Compressed Sparse Rows) format with two arrays where one array is the offset of each node and the second one are the edges. The data are read from a file, and I am using dictionary/map to reserve on memory. Then, it asks for the node and edge and using the BFS way of searching a graph, it must print if a path exists. However, no matter what I type, the program always returns that it found but does not print that it exists and the steps are 0.
The file looks like this:
737 6340
1740 1199
1738 1199
1738 1811
1738 2085
1739 1199
1741 214
1741 1199
1741 1419
1741 1496
1741 1723
The program looks like this:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct{
int* num;
int size;
int top;
} stack;
int nodesdoublesize(int** array,int n){
int* new_array=malloc(n*2*sizeof(int));
if(new_array==NULL){
printf("Error allocating memory\n");
abort();
}
n*=2;
for(int i=0;i<n;i++){
new_array[i]=(*array)[i];
}
free(*array);
*array=new_array;
return n;
}
void stack_destroy(stack *s){
free(s->num);
free(s);
}
int hashcmp(const void *a,const void *b){
return ( *(int*)a - *(int*)b );
}
int hashdoublesize(int** hash,int nodes){
int* new_array=malloc(nodes*2*sizeof(int));
if(new_array==NULL){
printf("Error allocating memory\n");
abort();
}
for(int i=0;i<nodes;i++){
new_array[i]=(*hash)[i];
}
nodes*=2;
free(*hash);
*hash=new_array;
return nodes;
}
typedef struct {
int start;
int end;
} path;
stack* stack_create(){
stack *s=malloc(sizeof(stack));
if(s==NULL){
printf("Error allocating memory for stack\n");
abort();
}
s->top=0;
s->size=10;
s->num=malloc(s->size*sizeof(int));
if(s->num==NULL){
printf("Error allocating memory\n");
abort();
}
return s;
}
int cmp(const void *a,const void *b){
int l=((path*)a)->start;
int r=((path*)b)->start;
if(l>r)
return 1;
if(l<r)
return -1;
else
return 0;
}
int doublesize(path** array,int n){
path* new_array=malloc(n*2*sizeof(path));
if(new_array==NULL){
printf("Error allocating memory\n");
abort();
}
for(int i=0;i<n;i++){
new_array[i]=(*array)[i];
}
free(*array);
*array=new_array;
n*=2;
return n;
}
int bfs(int* arraynodes,int* arrayedges,int n,int st,int end){
stack *s=stack_create();
int color[n];
for(int i=0;i<n;i++){
color[i]=-1;
}
color[st]=0;
s->num[s->top]=st;
while (s->top!=0){
for (int i = arraynodes[st]; i < arraynodes[st+1];i++){
if (color[i]==-1){
color[i]=0;
s->top++;
s->num[s->top]=i;
if(s->top==s->size){
s->top=nodesdoublesize(&s->num,s->size);
}
if(s->num[s->top]==end){
printf("Exists\n");
return 0;
}
}
s->top--;
color[i]=1;
}
}
return 1;
}
int main()
{
int maxsize=10;
int test;
char buff[200];
int counter=0;
char c;
int i;
path* array=malloc(maxsize*sizeof(path));
if(array==NULL) {
printf("Error allocating memory\n");
abort();
}
FILE* fd=fopen("Wiki-Vote.txt","r");
if(fd==NULL) {
printf("Error opening file\n");
abort();
}
while(fgets(buff,200,fd)) {
c=buff[0];
if(c=='#') {
continue;
}
sscanf(buff,"%d%d",&array[counter].start,&array[counter].end);
counter++;
if(counter==maxsize){
maxsize=doublesize(&array,maxsize);
}
}
maxsize=counter;
counter=0;
qsort(&array[0],maxsize,sizeof(path),cmp);
counter=1;
int nodes=10;
int* hash=malloc(nodes*sizeof(int));
if(hash==NULL){
printf("Error allocating memory\n");
abort();
}
for(i=0;i<maxsize;i++){
if(hash[counter-1]==array[i].start)
continue;
hash[counter]=array[i].start;
counter++;
if(counter==nodes){
nodes=hashdoublesize(&hash,nodes);
}
}
int j;
for(i=0;i<maxsize;i++){
for(j=0;j<counter;j++){
if(hash[j]==array[i].end)
break;
}
if(j!=counter)
continue;
hash[counter]=array[i].end;
counter++;
if(counter==nodes)
nodes=hashdoublesize(&hash,nodes);
}
nodes=counter;
qsort(&hash[0],nodes,sizeof(int),hashcmp);
int* arraynodes=malloc(nodes*sizeof(int));
int* arrayedges=malloc(maxsize*sizeof(int));
if(arraynodes==NULL||arrayedges==NULL){
printf("Error allocating memory\n");
abort();
}
int edge_count=maxsize;
int edge_offset=0;
for(int i=0;i<nodes;i++){
int current_node=hash[i];
arraynodes[i]=edge_offset;
while(edge_offset<edge_count&& array[edge_offset].start == current_node){
edge_offset++;
}
}
for (int i = 0; i < edge_count; i++){
arrayedges[i]=array[i].end;
}
int x;
printf("give number to search: ");
scanf("%d",&x);
for(i=0;i<nodes;i++){
if(x==hash[i]){
printf("found \n");
break;
}
}
if(i==nodes){
printf("not found \n");
abort();
}
/* for(j=arraynodes[i];j<arraynodes[i+1];j++){
printf("%d\n",arrayedges[j]);
}*/
int en=hash[i];
int st;
printf("From where would you like to start: ");
scanf("%d",&st);
printf("\n");
int found;
found=bfs(arraynodes,arrayedges,nodes,st,en);
if(found){
printf("Found\n");
}
else
printf("Not found\n");
free(arraynodes);
free(arrayedges);
free(hash);
fclose(fd);
free(array);
return 0;
}
Thank you for your time and any help will be apreciated.
Your stack_doublesize function is very wrong, and could be a reason behind your problems as using it will lead to undefined behavior.
Currently as shown (as I write this answer), it will basically reallocate a single stack structure into an array of 20 stack structures. It will then treat the single original stack structure as an array of 10 structure, and copy those 10 to the new array. This will of course go out of bounds since you don't have an array of 10 structures, only one single structure.
Furthermore you don't reallocate the memory pointed to by the stack structure itself, the num member will still be the same. That means you will go out of bounds of this memory as well.
As a solution for these issues I suggest you change your reallocation functions to something like this:
// Reallocate a dynamically allocated array, doubling its size
int nodesdoublesize(int **array,int n)
{
int* new_array = realloc(*array, n * 2 * sizeof *new_array);
if (new_array == NULL)
{
fprintf(stderr, "Out of memory\n");
abort();
}
*array = new_array;
return n * 2;
}
// Reallocate the data of the stack
void stack_doublesize(stack *s)
{
s->size = nodesdoublesize(&s->num, s->size);
}
Change your call to stack_doublesize to follow the new funciton.
There are probably more errors and problems in your code that I haven't found. I suggest you start by building with extra warnings enabled (-Wall -Wextra -Wpedantic if using GCC or Clang, and /W4 if using MSVC), and treat all warnings as errors that you need to fix.

C: Segmentation Fault 11 strcpy pointer Array

The code compiles with no errors, but I get a segmentation Fault Error (11), I'm guessing the problem is when I use the strcpy() function in line 82 ,something goes wrong, why im not getting any compile errors and how can I fix it, are the char array pointers well implemented?. I can not modiffy the current structs of the code.
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct
{
int n_uea;
char **nombre;
double *calificacion;
} UEA;
typedef struct
{
int n_pais;
char *nombre[50];
} PAIS;
typedef struct
{
char nombre[50];
UEA uea;
PAIS *pais;
} ALUMNO;
void AllocPais(PAIS *p, int np){
p = (PAIS*) malloc(sizeof(PAIS));
p = &p[0];
p->n_pais = np;
for (int i = 0; i < np; i++) {
p->nombre[i] = (char*) malloc(sizeof(char)*50);
}
}
void AllocUEA(UEA *u , int nu){
u->n_uea = nu;
u->nombre = (char **) malloc(sizeof(char*)*nu);
for (int i = 0; i < nu; i++) {
u->nombre[i] =(char*) malloc(sizeof(char)*50);
}
u->calificacion = (double*) malloc(sizeof(double) * nu);
}
void AllocAlumnoMemory(ALUMNO *a, int np, int nu){
AllocPais(a->pais,np);
AllocUEA(&(a->uea),nu);
}
int main(int argc, char const *argv[]) {
ALUMNO* arreglo;
int entradas;
printf("%s\n","Ingrese el numero de Entradas");
scanf("%d",&entradas);
arreglo = malloc(sizeof(ALUMNO)*entradas);
for (int i = 0; i < entradas; i++) {
char separator[10];
char name[20];
int numUea , numPaises;
printf("%s\n","Se espera separador");
scanf("%s",separator);
printf("%s\n","Ingrese el nombre");
scanf("%s",name);
strcpy(arreglo[i].nombre,name);
printf("%s\n","Ingrese el numero de UEA");
scanf("%d",&numUea);
AllocUEA(&arreglo[i].uea,numUea);
for (int a = 0; a < numUea; a++) {
char name [15];
double cal;
scanf("%s %lf", name, &cal);
strcpy(arreglo[i].uea.nombre[a],name);
arreglo[i].uea.calificacion[a] = cal;
}
printf("%s\n","Ingrese Numero de paises");
scanf("%d",&numPaises);
PAIS nuvp;
arreglo[i].pais = &nuvp;
AllocPais(arreglo[i].pais,numPaises);
for (int b = 0; b < numPaises; b++) {
char names [15];
scanf("%s",names);
strcpy(arreglo[i].pais->nombre[b],names);
}
}
return 0;
}
Please note down below points and try them:
Avoid using strcpy/strcat etc. they do not protect against buffer overruns.
Use strlcpy/strlcat instead.
When using strncpy, make sure to NULL terminate the string buffer.

double free or corruption (!prev) in c , using thread, malloc

I'm tired about this problem. I use valgrind also. but I don't know why. Please find what is the problem in my code.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static pthread_t *tid=NULL;
static int **data3=NULL;
typedef struct _Thdata
{
int *data;
int size;
int nthread;
} Thdata;
Thdata *tdata=NULL;
void *bubble(void *d){
Thdata *arr =(Thdata *)d;
int i,j,tmp;
int n=arr->size;
printf("thread #=%d n=%d\n",arr->nthread,n);
for(i=0;i<n;i++){
for(j=0;j<n-1;j++){
if((arr->data[j])>(arr->data[j+1]))
{
tmp = (arr->data[j]);
(arr->data[j])=(arr->data[j+1]);
(arr->data[j+1])=tmp;
}
}
}
for(j=0;j<n;j++)
printf("%d ",(arr->data[j]));
printf("\n");
pthread_exit((void *)1);
}
int main(int argc, char **argv){
FILE * fd;
int i,j;
int data[100];
int tcount = atoi(argv[1]);
int n = 100/tcount;
int err;
void *b;
//dynamic data
tid = (pthread_t *)malloc(tcount* sizeof(pthread_t));
data3 = (int **)malloc(tcount *sizeof(int*));
for( i=0; i<tcount; i++)
data3[i] = (int *)malloc((100/tcount) *sizeof(int));
tdata = (Thdata *)malloc(tcount*sizeof(Thdata));
for(i=0;i<tcount; i++) {
tdata[i].data =(int *)malloc(n*sizeof(int));
}
//dynamic data end
fd = fopen("data.txt", "r");
printf("tcount = %d n=%d\n",tcount,n);
// origin data
for(i =0; i<100;i++)
{
fscanf(fd, "%d",&data[i]);
printf("%d ", data[i]);
}
printf("\n");
for(j=0;j<tcount;j++){
for(i=0;i<n;i++){
data3[j][i]=data[n*j+i];
printf("%d ",data3[j][i]);
//tdata[j].data[i]=data[j][i];
}
printf("\n");
tdata[j].data=data3[j];
tdata[j].size=n;
tdata[j].nthread=0;
}
for(j=0;j<tcount;j++){
for(i=0;i<n;i++){
printf("%d ",tdata[j].data[i]);
}
printf("tdata[%d].size = %d",j,tdata[j].size);
printf("\n");
}
for(i =0; i<tcount;i++)
{
err=pthread_create(&tid[i],NULL,bubble,(void *)&tdata[i]);
if(err != 0)
printf("creat thread error");
tdata[i].nthread=i;
}
for(i=0;i<tcount;i++)
pthread_join(tid[i],&b);
for(i=tcount-1;i>=0;i--){
free(tdata[i].data);
}
free(tdata);
for(int i=tcount-1; i>=0; i--)
free(data3[i]);
free(data3);
free(tid);
fclose(fd);
return 0;
}
You assigned data3[j] to tdata[j].data as
tdata[j].data=data3[j];
so passing both of them to free() will cause double-free error as you said.
If you want to only copy pointers and copying values in data3[j] isn't needed, remove the part
for(i=0;i<tcount; i++) {
tdata[i].data =(int *)malloc(n*sizeof(int));
}
because the variable tdata[i].data will be overwritten later and memory leak will be caused. Also remove the part
for(i=tcount-1;i>=0;i--){
free(tdata[i].data);
}
because it will cause double-free error as descrived above.

"struct" objects with "for-loop" in C Programming

This code is about 'struct' in C..
I created a struct spieler with the properties name and age..
By using the for-loop I let the user to create the struct objects.
they are named as sp[i] --> sp1, sp2 etc.
the problem is the objects are created. But I can use them only inside the for-loop.
If I want to get the value of "sp1.name" in main function, it doesn't work.
How can I solve it?
struct spieler{
char name[20];
int age;
};
void erzeuge();
int main() {
int anzahl = 2;
printf("Anzahl Spielern: ");
scanf("%d",&anzahl);
erzeuge(anzahl);
printf("Es sind %d Spielern",anzahl);
/*for(i;i<anzahl;i++){
printf("%d.%s",i, sp[i].name);
}*/
getchar();
}
void erzeuge(int anzahl){
int i=0;
for(i;i<anzahl;i++){
struct spieler sp[i];
printf("Struct fuer Spieler_%d wurde erzeugt\n", i);
getchar();
printf("Name: ");
scanf("%s",sp[i].name);
printf("%s\n",sp[i].name);
}
You should declare sp as a pointer at the global scope, and allocate memory for it inside the function erzeuge using malloc.
#include <stdlib.h>
#include <stdio.h>
struct spieler {
char name[20];
int age;
};
struct spieler *sp; // Add this
void erzeuge();
int main() {
int anzahl;
printf("Anzahl Spielern: ");
scanf("%d", &anzahl);
erzeuge(anzahl);
printf("Es sind %d Spielern\n", anzahl);
int i;
for(i = 0; i < anzahl; i++){
printf("%d.%s\n", i, sp[i].name);
}
if (sp) {
free(sp);
}
getchar();
return 0;
}
void erzeuge(int anzahl) {
// Add the following line to allocate memory
sp = (struct spieler*) malloc(anzahl * sizeof(struct spieler));
int i;
for (i = 0; i < anzahl; i++) {
// Remove the following line because it create an array of "i" elements
// struct spieler sp[i];
printf("Struct fuer Spieler_%d wurde erzeugt\n", i);
getchar();
printf("Name: ");
scanf("%s",sp[i].name);
printf("%s\n",sp[i].name);
}
}
You'd have to return an array of players from erzeuge, something like
struct spieler *erzeuge(int anzahl){
struct spieler *mannschaft = malloc(anzahl*sizeof(struct spieler));
int i;
for(i = 0; i < anzahl; ++i){
// prompt
scanf("%18s",&mannschaft[i].name);
...
}
return mannschaft;
}
Alternative solution without malloc:
void erzeuge(struct spieler* sp, int anzahl)
{
...
}
int main()
{
int anzahl = 2;
...
struct spieler sp[anzahl];
erzeuge(sp,anzahl);
...
}

Resources