I have a structure defined as a char** array containing strings. I dont know how to run printf on its contents.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifndef STRUCT_STRING_ARRAY
#define STRUCT_STRING_ARRAY
typedef struct s_string_array
{
int size;
char** array;
} string_array;
#endif
void my_print_words_array(string_array* param_1)
{
int len = param_1->size;
char **d = param_1->array;
for(int i = 0 ; i < len;i++){
printf("%s\n", d[i]);
}
}
int main(){
struct s_string_array *d;
d->size = 2;
char **my_arr = (char *[]){"hello", "world"};//this init is fine
d->array = my_arr;
my_print_words_array(d);
return 0 ;
}
the main function gives me segfault error. What's wrong?
There is no sense to declare a pointer to the structure
struct s_string_array *d;
moreover that is not initialized and has indeterminate value that further is a reason of undefined behavior.
What you are trying to achieve is the following
#include <stdio.h>
typedef struct s_string_array
{
int size;
char** array;
} string_array;
void my_print_words_array( const string_array *param_1 )
{
for ( int i = 0; i < param_1->size; i++ )
{
puts( param_1->array[i] );
}
}
int main( void )
{
string_array d =
{
.size = 2,
.array = (char *[]){"hello", "world"}
};
my_print_words_array( &d );
return 0 ;
}
The program output is
hello
world
Related
I have a function that returns pointer to array of structures. However, when I try to access any of the values of returned structure, it prints random symbols.
#include <stdio.h>
struct MY {
int i;
char string[30];
};
struct MY* myFunc() {
struct MY arrayOfStructs[3];
struct MY tempStruct;
struct MY* arrayOfStructsPtr = arrayOfStructs;
tempStruct.i = 1;
tempStruct.string[0] = 'H';
tempStruct.string[1] = 'i';
arrayOfStructs[0] = tempStruct;
tempStruct.i = 2;
tempStruct.string[0] = 'L';
tempStruct.string[1] = 'o';
arrayOfStructs[1] = tempStruct;
tempStruct.i = 3;
tempStruct.string[0] = 'M';
tempStruct.string[1] = 'Y';
arrayOfStructs[2] = tempStruct;
return arrayOfStructsPtr;
}
int main()
{
struct MY* arrayOfStructs = myFunc();
for(int i = 0; i < 3; i++) printf("%d\n", arrayOfStructs[i].i);
return 0;
}
You return a reference to the local array which stops to exist when function returns. It is Undefined Behaviour.
You need:
struct MY* myFunc(void) {
static struct MY arrayOfStructs[3];
or
struct MY* myFunc(void) {
struct MY *arrayOfStructs = malloc(3 * sizeof(*arrayOfStructs));
or pass the buffer allocated by the caller.
struct MY *myFunc(struct MY *arrayOfStructs) {
/* .... */
If you dynamically allocate memory you should free it after use
You return a pointer to a local variable which is out of scope when the function returns. Some alternatives:
The caller main() allocates variable and pass it to myFunc() for initialization.
#include <stdio.h>
#include <string.h>
#define N 3
struct MY {
int i;
char string[30];
};
void myFunc(struct MY arrayOfStructs[N]) {
char *strings[N] = { "Hi", "Lo", "MY" };
for(size_t i = 0; i < N; i++) {
arrayOfStructs[i].i = i + 1;
strcpy(arrayOfStructs[i].string, strings[i]);
}
}
int main() {
struct MY arrayOfStructs[N];
myFunc(arrayOfStructs);
for(int i = 0; i < N; i++)
printf("%d\n", arrayOfStructs[i].i);
}
As used here you don't really need to store i as it's just index of the struct + 1.
myFunc() dynamically allocate the variables with malloc() and return the pointer. Caller is responsible for free'ing the allocated memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3
struct MY {
int i;
char string[30];
};
struct MY *myFunc() {
struct MY *arrayOfStructs = malloc(N * sizeof *arrayOfStructs);
if(!arrayOfStructs) return NULL; // malloc failed
char *strings[N] = { "Hi", "Lo", "MY" };
for(size_t i = 0; i < sizeof strings / sizeof *strings; i++) {
arrayOfStructs[i].i = i + 1;
strcpy(arrayOfStructs[i].string, strings[i]);
}
return arrayOfStructs;
}
int main() {
struct MY *arrayOfStructs = myFunc();
if(!arrayOfStructs) return 1;
for(int i = 0; i < N; i++)
printf("%d\n", arrayOfStructs[i].i);
free(arrayOfStructs);
}
myFunc(): make variables static (not recommended).
I'm implementing a data structure in C and I get this error in my test file. Without adding code because then that would be a huge post with a ton of code to go through, but here's what my code looks like:
header.h file:
typedef struct array Arr;
functions.c file:
#include "header.h"
struct array{
int number;
int size;
char *names;
}
main.c file:
#include "header.h"
bool function(const Arr *const variable)
{
for (int i = 0; i < variable->size; i++)
{
variable->number[i] = i;
}
}
and so I get the error mentioned in the title referring to Arr*->number and Arr->*size. What I suspect to be the issue is that Arr is only typedefed but not defined. If that's the case, how can I resolve it?
Here's the main code:
main.c
#include <stdio.h>
#include "header.h"
int main(){
set *setA = set_empty();
set_insert(69,setA );
set_insert(15, setA);
set *setB = set_empty();
set_insert(12,setB );
set_insert(15, setB);
set *setDiff = set_difference(setA, setB);
printf("\n");
print_set(setDiff);
bool diff = verify_difference(setDiff, setA, setB);
}
bool verify_difference(const set *const setDiff, const set *const setA, const struct set *const setB)
{
bool answer = true;
for (int x = 0; x < setDiff->size; x++)
{
if (set_member_of(setDiff->array[x], setA) && set_member_of(setDiff->array[x], setB))
{
answer = false;
break;
}
}
return answer;
}
header.h
#ifndef HEADER_H
#define HEADER_H
#include <stdbool.h>
typedef struct set set;
set *set_empty();
void set_insert(const int value, set *s);
bool set_member_of(const int value, const set *const s);
functions.c
#include <stdio.h>
#include "header.h"
struct set {
int capacity;
int size;
char *array;
};
set *set_empty()
{
struct set *ptr = malloc(sizeof(struct set));
ptr->size = 0;
ptr->array = malloc(sizeof(char));
ptr->capacity = 1;
return ptr;
}
void set_insert(const int value, set *s)
{
if (!set_member_of(value, s)) {
int bit_in_array = value; // To make the code easier to read
// Increase the capacity if necessary
if (bit_in_array >= s->capacity) {
int no_of_bytes = bit_in_array / 8 + 1;
s->array = realloc(s->array, no_of_bytes);
for (int i = s->capacity / 8 ; i < no_of_bytes ; i++) {
s->array[i] = 0;
}
s->capacity = no_of_bytes * 8;
}
// Set the bit
int byte_no = bit_in_array / 8;
int bit = 7 - bit_in_array % 8;
s->array[byte_no] = s->array[byte_no] | 1 << bit;
s->size++;
}
}
set *set_difference(const set *const s1, const set *const s2)
{
struct set *s = set_empty();
for (int i = 0; i < s1->size; i++)
{
if (!set_member_of(s1->array[i], s2))
{
set_insert(s1->array[i], s);
}
}
for (int i = 0; i < s2->size; i++)
{
if (!set_member_of(s2->array[i], s1))
{
set_insert(s2->array[i], s);
}
}
return s;
}
bool set_member_of(const int value, const set *const s)
{
int bit_in_array = value;
if (bit_in_array >= s->capacity) {
return false;
}
int byte_no = bit_in_array / 8;
int bit = 7 - bit_in_array % 8;
char the_byte = s->array[byte_no];
return the_byte & 1 << bit;
}
The definition of the structure shall be available in main. Otherwise the compiler does not know whether there is the data member number in the structure referred in this statement
Arr->number[i] = i;
Moreover in any case this statement is incorrect because Arr is a type specifier and according to the structure definition the data member number is not an array
It seems you mean
variable[i].number = i;
But as the function parameter
bool function(const Arr *const variable)
is declared as a pointer to a constant object then you may not change pointed to data members of the structure.
So either move the definition of the function function from main.c in functions.c or place the structure definition in the header file.
And there is a typo
Typedef struct array Arr;
^^T
you need to use lower case letter
typedef struct array Arr;
I can only hazard a guess. Your code snippet could be wrong.
Move the structure definition to header.h & check.
//header.h file:
typedef struct array Arr;
struct array{
int number;
int size;
char *names;
};
I have a struct
struct cmd{
char **tokenized_cmd;
int num_params;
}
at some point i need to initialize tokenized_cmd and pass values from another array into it
how to do that?
#include <stdio.h>
char *arr[] = {"one", "two"};
struct cmd {
char **tokenized_cmd;
int num_params;
} x = {arr, 2};
int main(void)
{
int i;
for (i = 0; i < x.num_params; i++)
printf("%s\n", x.tokenized_cmd[i]);
return 0;
}
or
#include <stdio.h>
struct cmd {
char **tokenized_cmd;
int num_params;
};
int main(void)
{
char *arr[] = {"one", "two"};
struct cmd x = {arr, 2};
int i;
for (i = 0; i < x.num_params; i++)
printf("%s\n", x.tokenized_cmd[i]);
return 0;
}
or the more flexible:
#include <stdio.h>
#include <stdlib.h>
struct cmd {
char **tokenized_cmd;
int num_params;
};
struct cmd *cmd_init(char **token, int params)
{
struct cmd *x = malloc(sizeof *x);
if (x == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
x->tokenized_cmd = token;
x->num_params = params;
return x;
}
int main(void)
{
char *arr[] = {"one", "two"};
struct cmd *x = cmd_init(arr, 2);
int i;
for (i = 0; i < x->num_params; i++)
printf("%s\n", x->tokenized_cmd[i]);
free(x);
return 0;
}
I wonder if I'm doing something wrong in my program.
I manage to create a HashTable but when I send it through parameter to my displayingList() function, it crashes.
source.c (contains my functions):
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include "header.h"
#define MAX 255
int countLetters(char myStr[])
{
int myLen = strlen(myStr), i;
int wordLen = 0;
for (i = 0 ; i < myLen; ++i)
{
wordLen += (int)(myStr[i]);
}
return (wordLen%256);
}
void populateList(NodeT *T[255], char myStr[])
{
NodeT *p, *q;
p = (NodeT *)malloc(sizeof(NodeT));
strcpy (p->key, myStr);
int myPos = countLetters(myStr);
if(T[myPos] == NULL)
{
p->next = NULL;
T[myPos] = p;
}
else
{
q = T[myPos];
p->next = q;
T[myPos] = p;
}
}
void displayList(NodeT *T[255])
{
int i;
NodeT *p;
for(i = 0 ; i < 255; ++i)
{
if(T[i] != NULL)
{
printf("Index: %d - Data:", i);
p = T[i];
while(p != 0)
{
printf("%s, ", p->key); // HERE IT CRASHES.
p = p->next;
}
printf("\n");
}
}
}
main.c (contains the int main()):
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
int main(void)
{
NodeT *T[255];
int n, i;
printf("Give no. of elements:");
scanf("%d", &n);
fflush(stdin);
for(i = 0 ; i < n ; ++i)
{
char name[100];
gets(name);
populateList(T, name);
}
displayList(T);
return 0;
}
header.h (and my header):
#ifndef HEADER_H
#define HEADER_H
typedef struct cell
{
char key[100];
struct cell *next;
}NodeT;
int countLetters(char myStr[]);
void populateList(NodeT *T[], char myStr[]);
void displayList(NodeT *T[]);
#endif // HEADER_H
I tried to see what exactly happens with debugger and it seems that when I send T[] list to displayList() function, actually it doesn't have the same structure as it has in main.c.
ISSUE: the insertion works fine, but when I try to display my list (on each index) it crashes.
Any ideas?
Thanks in advance.
The possible solution is to declare the NodeT *T[255] global. However it isn't the best practice at all.
Hey All, I am a pointer newbie and in the following code, I am trying to store the values of a 2 D array in a structure and then print them. However, I get a compilation error at the line: fd->mychar[i] = newptr[i]; I get that while char * str is same as str[], char ** str isnt the same as str[][], but I cant find a solution to make the following work.
typedef struct mystruct{
char mychar [20][20];
}mystruct_t;
void printvalues ( char ** newptr){
int i;
mystruct_t * fd;
for (i=0;i<3;i++){
fd->mychar[i] = newptr[i];
printf("My value is %s and in struct %s\n", newptr[i], fd->mychar[i]);
}
}
int main (int argc, char **argv){
int i;
char * abc[5] = {"123", "456", "789"};
for (i=0;i<3;i++){
printf("My value is %s\n", abc[i]);
}
printvalues(abc);
}
Most of the issue was your use of an unallocated structure.
You used a pointer to mystruct_t but never allocated it.
The following runs for me:
#include <stdio.h>
typedef struct mystruct
{
char* mychar [20];
} mystruct_t;
void printvalues( char** newptr )
{
int i;
// note: you used an unallocated pointer in your original code
mystruct_t fd;
for ( i = 0; i < 3; i++ )
{
fd.mychar[i] = newptr[i];
printf( "My value is %s and in struct %s\n", newptr[i], fd.mychar[i] );
}
}
int main( int argc, char **argv )
{
int i;
char * abc[5] = { "123", "456", "789" };
for ( i = 0; i < 3; i++ )
{
printf( "My value is %s\n", abc[i] );
}
printvalues( abc );
}