I'm trying to make a dynamic char array, but I'm running into issues. I get segmentation fault when I try to add anything to the array.
static int arrays()
{
int INITIAL = 1;
char **all_words;
all_words = (char**)malloc(INITIAL*sizeof(*all_words));
int currentSize = INITIAL;
for(int i = 0; i < counter; i++){
all_words = realloc(all_words,currentSize*sizeof(*all_words));
strcpy(all_words[i], "hello");
currentSize++;
}
for(int i = 0; i < counter; i++){
printf("%s ", all_words[i]);
}
}
I pretty much copied this from a guide online, so I'm not sure why it wouldn't work.
You've correctly allocated an array of char *, however those pointers remain uninitiaized. So when you then do this:
strcpy(all_words[i], "hello");
You're dereferencing an invalid pointer.
Each element of all_words needs to point to allocated space. This simplest way to do this is to use strdup if your system supports it instead of strcpy:
all_words[i] = strdup("hello");
Otherwise you would use malloc to allocate the space, then use strcpy
all_words[i] = malloc(sizeof("hello"));
strcpy(all_words[i], "hello");
Related
So, my goal was to define a struct in which there is -
A command name (e.g. - "print")
Command arguments counter
A strings array containing the arguments.
You can review my code, but I'm really having a hard time understanding what am I doing wrong -
I use malloc to dynamically set my_struct.command size
I use malloc to dynamically set my_struct.arguments array size
I use realloc to dynamically increase my_struct.arguments size for every argument I set
I use malloc to dynamically set my_struct.arguments[i] size
I finally call cleanup(), to free any dynamically assigned pointers.
I keep getting LOTS of memory leaks. But I cannot understand why.
Help and tips will be kindly appreciated.
#include <stdio.h>
#include <stdlib.h>
struct {
char *command;
int arguments_count;
char **arguments;
} my_struct;
void cleanup(void);
int main() {
int i;
my_struct.command = (char *)malloc(6*sizeof(char));
my_struct.command = "print";
my_struct.arguments_count = 1;
my_struct.arguments = (char **)malloc(sizeof(char *));
my_struct.arguments[0] = "hello";
for(i = 1 ; i < 10; i++) {
my_struct.arguments = (char **)realloc(my_struct.arguments, sizeof(char *)*(i+1));
my_struct.arguments[i] = (char *)malloc(8*sizeof(char));
my_struct.arguments[i] = "hello";
my_struct.arguments_count++;
}
printf("Arguments count is: %d\n", my_struct.arguments_count);
printf("The arguments are:\n");
for(i = 0; i < 10; i++) {
printf("%s\n", my_struct.arguments[i]);
}
cleanup();
exit(0);
}
void cleanup(void) {
int i;
for(i = 0; i < 10; i++)
free(my_struct.arguments[i]);
free(my_struct.arguments);
free(my_struct.command);
}
strdup - The strdup() function returns a pointer to a new
string which is a duplicate of the string s. Memory for the new
string is obtained with malloc, and can be freed with free.
my_struct.command = strdup("print");
my_struct.arguments_count = 1;
my_struct.arguments = (char**) malloc(sizeof(char*));
my_struct.arguments[0] = strdup("hello");
for (int i=1; i < 10; ++i) {
// if the number of args is known, allocate before entering the loop
my_struct.arguments = (char**) realloc(my_struct.arguments, sizeof(char*)*(i+1));
my_struct.arguments[i] = strdup("hello");
my_struct.arguments_count++;
}
// in your cleanup use the arguments_count var instead of the literal 10
for (int i=0; i < my_struct.arguments_count; ++i)
Your mistake was:
// allocate a memory block of 6 bytes
// assign the address of that block to command
my_struct.command = malloc(6);
// then you assigned the address of the string 'print' to command
// therefore the previous allocated block is lost -> mem leak
my_struct.command = "print";
// strdup does the following
return memcpy(malloc(strlen(str) + 1), str, strlen(str) + 1);
I have an array of strings that is dynamically sized (I won't know the size of the strings at compile) that keeps giving me a segmentation fault error. The array is contained in a struct called hm and it has an array for the strings as well as an array for values. This part of the code is only to resize the string array properly when a new string is added to the struct.
I am relatively new to C and structs, so if there is a better way to implement this I would love to hear about it. I have already tried looking around for this situation and most seem to be having the issue with the outer array using sizeof(char) instead of sizeof(char*), but when I changed that the issue still happens.
//problematic part of the function
char** t = (char**)realloc(hm->keys, hm->size * sizeof(char*));
if (t) hm->keys = t;
for (i = 0; i < hm->size; i++) {
char* temp = (char*)realloc(hm->keys[i], hm->largestKey * sizeof(char)); //seg fault here
if (temp) {
hm->keys[i] = temp;
}
}
//struct
typedef struct HM_struct {
size_t size;
size_t largestKey;
char** keys;
int* values;
void (*add)(struct HM_struct* hm, char* key, int value);
} HM;
The problem is that when you realloc() and increase the allocated memory size, the new memory is not initialised (or with a debug library, initialised to a sentinal value). So, assuming you know the oldSize, a quick fix is:
char** t = realloc(hm->keys, hm->size * sizeof(char*)); // As before
if (t) hm->keys = t; // As before
for (i = oldSize; i < hm->size; i++)
hm->keys[i] = NULL;
Now, according to the realloc() definition, when you call:
char* temp = realloc(NULL, hm->largestKey * sizeof(char));
It behaves as:
char* temp = malloc(hm->largestKey * sizeof(char));
I have created double pointer char to be used as a 2d array to store strings. The append function is meant to add the string provided to the end of the array, the num_strings pointer is provided to keep track of the elements in the array (since I can't use sizeof). It seems that at some point, the function isn't allocating enough memory but I can't seem to figure out where and can't find any other issues.
I have already tried giving both the outer array and the inner array large amounts of memory, much more than they need. The issue persists. I have also tried copying the string to the array after the function had run.
int main(int argc, char *argv[]) {
char **strings = NULL;
int num_strings = 0;
append(&strings, &num_strings, "Alex");
append(&strings, &num_strings, "Edward");
// Do things with array
for (int i = 0; i < num_strings; i++) {;
printf("%s\n", strings[i]);
}
// Free memory after use
for (int i = 0; i < num_strings; i++) {
free(strings[i]);
}
free(strings);
strings = NULL;
return 0;
}
void append(char ***array, int * num_strings, char *string) {
if (*array == NULL) {
*array = malloc(sizeof(*array)); // start with enough room for 1 item (pointer)
} else {
// reallocate memory for new item
*array = realloc(*array, (((*num_strings) + 1) * sizeof(*array)));
}
printf("Char Size: %lu\n", sizeof(char));
printf("Given Size: %lu\n", sizeof(***(array)));
*(array[*num_strings]) = malloc((strlen(string) + 1) * sizeof(***(array + 0)));
strcpy(*(array[*num_strings]), string);
(*num_strings)++; // increment the number of strings
}
The output of the program should be the two strings, at the moment it only prints the first and then crashs due to the segmentation fault.
The problem is there are a couple instances of *(array[*num_strings]) that should be (*array)[*num_strings].
The difference is that the first form tries to index through the pointer passed to the function, as if the passed strings were an array, corrupting the caller's stack. The corrected version first derefernces the pointer, then indexed through the target as desired.
There are also a few places where sizeof(*array) is used where it should be sizeof(**array). x = malloc(sizeof(x)) is never correct. But this isn't causing a visible problem.
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
void createDynamicArrayForChar(int dimension, char **ptr)
{
ptr = (char**)malloc(dimension*sizeof(char*));
for (int i = 0; i < dimension; i++)
{
ptr[i] = (char*)malloc(20 * sizeof(char));
ptr[i] = "value";
}
}
int main()
{
char **ptrArray;
createDynamicArrayForChar(5, ptrArray);
printf("%s", ptrArray[3]);
getchar(); getchar();
return 0;
}
It gives some errors when I try to compile this codes. How can I solve this problem? How to send 2D char pointer to a function in C?
Firstly, as per the present code, I see two issues.
You're passing ptrArray to the function and trying to allocate memory inside the function. Please be aware, C uses pass by value for function argument passing, so, if you want to allocate memory to ptrArray and expect that to be refeclted back to the caller, without returning, you'll be needing to pass a pointer to that `ptrArray.
in the code
ptr[i] = (char*)malloc(20 * sizeof(char));
ptr[i] = "value";
You're leaking memory. Once you've allocated memory using malloc(), you should use strcpy() to copy the data into the allocated memory.
That said, some advice:
Please see why not to cast the return value of malloc() and family in C.
sizeof(char) is guaranteed to be 1 in C. Using that as a multiplier is not required.
Always check the success of malloc() before using the returned pointer.
You probably need this (no error checking and not debugged code):
void createDynamicArrayForChar(int dimension, char ***ptr)
{
*ptr = (char**)malloc(dimension*sizeof(char*));
for (int i = 0; i < dimension; i++)
{
(*ptr)[i] = (char*)malloc(20 * sizeof(char));
strcpy((*ptr)[i],"value");
}
}
or
char **createDynamicArrayForChar(int dimension)
{
char **ptr = (char**)malloc(dimension*sizeof(char*));
for (int i = 0; i < dimension; i++)
{
ptr[i] = (char*)malloc(20 * sizeof(char));
strcpy(ptr[i],"value");
}
return ptr;
}
int main()
{
char **ptrArray;
ptrArray = createDynamicArrayForChar(5);
...
Read also Sourav Ghosh's answer.
I am attempting to set the last element in a second char ** array to NULL after I encounter a specific char in the first array.
int test(char ** args){
char ** chmd1;
for(int i = 0; args[i] != NULL; ++i){
if(!strncmp(args[i], "<", 1)){
chmd1[i] = NULL;
break;
}
chmd1[i] = args[i];
}
for(int i = 0; chmd1[i] != NULL; ++i){
printf("%s", chmd1[i]);
}
return 0;
}
This code segfaults as the second for loop goes on for more iterations past where the NULL should be.
I want to be able to be able to do this just by manipulating pointers and not using any mallocs, but I'm completely stuck.
This code segfaults as the second for loop goes on for more iterations past where the the NULL should be.
You have not allocated memory for chmd1 and yet you are using it like it points to valid memory.
I want to be able to be able to do this just by manipulating pointers and not using any mallocs, but I'm completely stuck.
You can't do that. You have use malloc (or one of the other functions from the malloc group of functions: calloc, realloc) to allocate memory for chmd1 before you can use it.
allocate memory for pointer
char ** chmd1;
I want to be able to be able to do this just by manipulating pointers and not using any mallocs, but I'm completely stuck.
Without allocating memory to chmd1, it will not be possible.
You have to allocate memory for char ** chmd1; before assigning value NULL (or copy elements from args) to any element.
It can be something like
char ** chmd1 = malloc(NUMBER * sizeof(char*));
or even
char * chmd1[NUMBER];
To determine NUMBER value find the NULL in the args first.
EDIT:
Also you can use realloc in your loop as:
char **chmd1 = NULL;
int i;
for(i = 0; argv[i] != NULL; ++i){
chmd1 = (char**)realloc(chmd1, i * sizeof(char*) );
if(!strncmp(argv[i], "<", 1)){
chmd1[i] = NULL;
break;
}
chmd1[i] = argv[i];
}
// then use i as size of chmd1
for(int cnt = 0; cnt < i; cnt++)
{
if( chmd1[i] == NULL ) ; // do something
}
chmd1[i] = args[i];
chmd[i] is a pointer in 2D space and you are not allocating memory for the pointer.