-1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int* create_int_array(){
   int* arr;
   arr = (int *)calloc(1,sizeof(int));
   return arr;
}


char** create_string_array(){
   char** arr = calloc(1,sizeof(char));
   return arr;
}

void append_int(int* array, int element, int index){
  array = (array+index);
  *array = element;
}

void append_string(char** array , char* element,int index){
  *(array + index) = calloc(1,sizeof(char*));
  strcpy(*(array + index),element);
}

void delete_string(char** array, int index){
  free(array[index]);
}

void delete_int(int* array,int index){
  array[index] = NULL;
}

/////// M A I N   F I L E ///////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "basic_data_file.h"

int main(int argc, char const *argv[])
{
  /* code */
  char **array;
  array = create_string_array();

  char *full_name = calloc(strlen("hamza arslan"),sizeof(char*));
  strcpy(full_name,"hamza arslan");

  char* mail = calloc(strlen("test@gmail.com"),sizeof(char*));
  strcpy(mail,"test@gmail.com");

  char* address = calloc(strlen("Hacettepe Universty"),sizeof(char*));
  strcpy(address,"Hacettepe Universty");

  char* statu = calloc(strlen("student"),sizeof(char*));
  strcpy(statu,"student");

  append_string(array,full_name,0);
  append_string(array,mail,1);
  append_string(array,address,2);
  append_string(array,statu,4);

  for(int i=0; i< 3; i++){
    printf("%s\n",array[i]);
    free(array[i]); // get free double pointer
  }
  printf("%s\n",array[4]); // because index 3 blow up

  free(full_name);
  free(mail);
  free(address);
  free(statu);
  return 0;
}

I was try to own my basic array library . As you know else in some languages have high level array types. They are making easy our stocking operation. But in c, it's more complicated especially about string. I have 2 problem in here . First of all , when i give index=3 in append_string function , code blow up with Aborted(core dumped) error.(./run': double free or corruption (out)). Secondly , when i was checking leak memory ,it's get memory leak even i use free. What can i do?

claymorehack
  • 78
  • 10
  • 1
    Please format the code properly. – Eugene Sh. Jul 10 '18 at 17:31
  • One of the first things to learn when programming is how to keep your code organized. Please pay particular attention to indentation. This communicates intent and structure and is especially important for us when trying to quickly review your code. – tadman Jul 10 '18 at 17:32
  • When you say "array" do you mean "string buffer"? This looks like `append_string` is a reimplementation of `strcat` with some allocation features. It's also not really C-style to send in a mutable pointer (`char**`), but instead to return a pointer instead of `void`. This code is also *full* of memory leaks because it doesn't properly release the old buffer when reallocating and appending. – tadman Jul 10 '18 at 17:32

3 Answers3

1

Your create_xy_array functions allocate an array of 1 element, and they stay that way until the very end. When you have a one-element array and index, read/write its second and further elements, C itself happily approves, but the result will not work, it silently destroys everything in its path.

First of all, for having a dynamic array, you have to track its length yourself, C allocations/arrays do not know their own size. So you need a struct, containing the length and a pointer, something like

typedef struct IntArray {
  int length;
  int *elements;
} IntArray;

Then allocate it, for 0 elements, as there is nothing inside at the beginning:

IntArray* create_int_array() {
  IntArray* ret = (IntArray*) malloc(sizeof(IntArray));
  ret->length = 0;
  ret->elements = NULL;
  return ret;
}

void free_int_array(IntArray* arr) {
  free(arr->elements);
  free(arr);
}

Then you can try putting something inside:

void append_int(IntArray* arr, int element) {
  arr->length++;
  arr->elements = (int*) realloc(arr->elements, arr->length*sizeof(int));
  arr->elements[length-1] = element;
}

(appending means adding something to the end of an array, there is no need for indices here)

And this could go on forever, deletion of an arbitrary element should shift the "upper" part of the array (memcpy) and resize the result to one element smaller or you could track the capacity of the array, which can be larger than its current length (but then it has to be incorporated into the append function and probably others).

(Disclaimer: I hope the snippet is correct, but I do not use C too often - and I can not suggest a good tutorial for the same reason, but that is what you probably need)

tevemadar
  • 12,389
  • 3
  • 21
  • 49
0

There will be several crashes, but here is one:

   char** arr = calloc(1,sizeof(char));

You are allocating 1 byte which is not sufficient to store a (char *), which needs between 2 and 8 bytes depending on the OS and target machine.

Try this instead:

   char** arr = calloc(1,sizeof(char*));

You should double-check each line of code. C is not a forgiving language - mistakes are severely punished.

  • it still giving leak, didn't change anything. – claymorehack Jul 10 '18 at 17:41
  • @claymorehack See my answer about memory leaks [here](https://stackoverflow.com/questions/5134891/how-do-i-use-valgrind-to-find-memory-leaks/44989219#44989219). I think I see your leak though. When you have a 2D array, you have a list of pointers. The list itself is also a pointer (I'm implying dynamically allocated here). Are you freeing all of those? –  Jul 10 '18 at 17:42
  • @JoshDetwiler last of the main file i get free in for loop double pointer , but might be problem which allocate memory in function. But how can get them free? I want to use and of the program, then free! . I try to convert to c array's python list type. – claymorehack Jul 10 '18 at 17:52
  • @claymorehack I'm sorry, I didn't understand any of that. –  Jul 10 '18 at 17:54
  • @Josh Detwiler I mean I get free 2d array end of the code using for loop . Is it right ? – claymorehack Jul 10 '18 at 18:04
  • @claymorehack Where do you free the 2D array itself? You dynamically allocated that too. You can't just free its entries---you need to free your `array` variable as well. –  Jul 10 '18 at 18:06
0

Note: I haven't code in C for years and I haven't check the code so double check and let me know.

Based on your description, you are trying to do a Vector.

Therefore, there are different ways that you can handle this.

Approach 1:

Create a structure which will hold the array, the capacity of the array, and the size of the array.

typedef struct StrArray{
    int capacity;
    int size;
    int *integers;
}

The trick here is to take attention when you increase/decrease the capacity.

If you increase the capacity above the size of the array, then:

  • You need to create a new array with double the capacity
  • Copy all elements to the new array
  • Change pointer to new array
  • Free the memory of the old array

Approach 2

You can extend the previous approach by creating a function which returns a struct which holds the storage plus function pointers to the methods you wish to implement.

typedef struct StrStorage{
    int capacity;
    int size;
    int *integers;
} StrStorage;

typedef struct StrArray {
    StrStorage storage;
    int (*capacity)(StrArray*);
    int (*size)(StrArray*);
    StrArray *(*append)(StrArray*, int);
    void (*increaseStorage)(StrArray*);
    // Add other methods here
} StrArray;

int capacity(StrArray *self) {
    return self->storage->capacity;
}

int size(StrArray *self) {
    return self->storage->size;
}

StrArray *append(StrArray *self, int integer){
    if ((self->capacity() + 1) > self->size()){
        self->increaseStorage();
    }
    // The rest of the magic goes here
    return self;
}

StrArray *initializeStrArray(int n) {
    StrArray* strArray = malloc(sizeof(StrArray));
    strArray->chars = malloc(sizeof(char) * n);
    strArray->capacity= capacity;
    strArray->append = append;
    return strArray;
}

Approach 3:

This approach is a continuation of the previous one.

In order to reduce the memory allocation, you can create an equivalent to a singleton which holds all the manipulation functions and then assi

acarlstein
  • 1,799
  • 2
  • 13
  • 21