-2

● int vectorInsert(Vector * array, int index, Data value);

I am doing

If this can be corrected according to the given statement.

I am calling it using

Vector *vect = initVector();
Data data_array[20];
for(i = 0 ; i < 20 ; i++){
    data_array[i].value = (rand() % 20) + 1;
    vectorInsert(vect, i, data_array[i]);
}
King
  • 15
  • 1
  • 7
  • 2
    Is there a problem with the code that you have posted? What are you asking? – ad absurdum Nov 03 '16 at 14:22
  • also is `Vector` a type you have created, or is this the C++ standard library `Vector` – Mobius Nov 03 '16 at 14:24
  • Vector i have created, i have edited the code again. – King Nov 03 '16 at 14:26
  • That's helpful, @King, but it's still unclear what your actual question is. – John Bollinger Nov 03 '16 at 14:27
  • @DavidBowling Yes i have a issue its not matching the statement which i have to follow. – King Nov 03 '16 at 14:27
  • initVector does not seem to be right. You are accessing random memory – Marek Klein Nov 03 '16 at 14:28
  • @JohnBollinger I have to inserts an` element at the specified index. Use the 2n+1 geometric expansion formula to increase the size of your list if the index is out of the current bounds. Should return a 1 upon successful insert and 0 on memory allocation error – King Nov 03 '16 at 14:28
  • Specifically, what is your code doing that diverges from your expectations? – ad absurdum Nov 03 '16 at 14:28
  • @MarekKlein Can you help me as to what I did wrong? – King Nov 03 '16 at 14:29
  • @DavidBowling I am not able to return accoring to what is asked in the problem statement. – King Nov 03 '16 at 14:30
  • As @MarekKlein pointed out, in `initVector()` you declare a pointer to `Vector`, and then proceed to access its members without initializing it. – ad absurdum Nov 03 '16 at 14:32
  • @DavidBowling If you can tell how to go about it as I am new to it – King Nov 03 '16 at 14:35
  • Can you provide pieces of code where you initialize vector? I believe you want to return pointer to vector `v`, not `data`. Furthermore, when calling `vectorInsert` with index higher than `array->max_size` you allocate new memory for data but you lose the pointer to old data. Maybe you can have a look at `realloc` – Marek Klein Nov 03 '16 at 14:35
  • You should not expect us to do your homework.I voted to close. But do compile your code with all warnings & debug info (`gcc -Wall -g`) then use the debugger (`gdb`). BTW `v` is an uninitialized pointer in `initVector` so you have [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior) - and your compiler would have warned you – Basile Starynkevitch Nov 03 '16 at 14:37
  • I reedited the post – King Nov 03 '16 at 14:40
  • @MarekKlein I did so if you can have a look – King Nov 03 '16 at 14:42

3 Answers3

1

There are a couple of errors in your code, but the most important one is in your initVector function, you actually need to allocate memory for the vector.

You also need to do the following things:

  • in initVector return v instead of v->data or &v
  • in vectorInsert print array->data[index].value instead of array->data[index]
  • in vectorInsert return 1 on success, add error checking in your allocation and return 0 on memory error.

All of these except the original malloc were warnings returned by the compiler.

Mobius
  • 2,871
  • 1
  • 19
  • 29
  • How to go about the 3rd part? – King Nov 03 '16 at 14:56
  • Look in my answer. I handled *crudely* allocation failures. – Basile Starynkevitch Nov 03 '16 at 14:57
  • 1
    in case you didn't know, you can have multiple `return` statements in a function, the first one you get to will end the function, so if you run into an error, you can use an if statement to check for that error, and inside the if statement run `return 0` – Mobius Nov 03 '16 at 14:59
  • 1
    take a look at the man page for `malloc` https://linux.die.net/man/3/malloc in the **Return** section, it talks about what happens on an error. – Mobius Nov 03 '16 at 15:01
0

Enable all warnings and debug info in your compiler (e.g. compile with gcc -Wall -g). Then it should warn you about

Vector * initVector(){
 Vector *v; /// UNINITALIZED
v->max_size=0;
v->current_size=0;
v->data = malloc(sizeof(int)*v->max_size);
return v->data;
//      return (&v);
} 

So you have an undefined behavior, and that is awfully bad.

(Of course the compiler will give a lot of other warnings, and you should improve your code till you got no warnings at all. Then you should use the gdb debugger)

You might want to read about flexible array members.

Consider perhaps having at least:

Vector* createVector(int maxsize) {
  if (maxsize<=0) 
    { fprintf(stderr, "bad maxsize=%d\n", maxsize); exit(EXIT_FAILURE); };
  Vector* v = malloc(sizeof(Vector));
  if (!v) { perror("malloc Vector"); exit(EXIT_FAILURE); };
  v->data = malloc(sizeof(Data)*maxsize);
  if (!v->data) { perror("malloc data"); exit(EXIT_FAILURE); };
  v->max_size = maxsize;
  v->current_size = 0;
  memset(v->data, 0, sizeof(Data)*maxsize);
  return v;
}
Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • program5.c: In function ‘initVector’: program5.c:23:3: warning: return from incompatible pointer type [enabled by default] program5.c: In function ‘vectorInsert’: program5.c:37:4: warning: incompatible implicit declaration of built-in function ‘memcpy’ [enabled by default] program5.c:51:4: warning: return makes integer from pointer without a cast [enabled by default] program5.c:51:4: warning: function returns address of local variable [enabled by default] I am not able to correct the warnings. – King Nov 03 '16 at 14:48
  • Then, don't ask questions in a forum before correcting all warnings. But do take several hours to read more deeply your C tutorial or a good C programming book. – Basile Starynkevitch Nov 03 '16 at 14:49
  • I cannot use int maxsize as parameter, no parameter should be there – King Nov 03 '16 at 15:02
  • Then ask your teacher if you are allowed to define an initial `maxsize` (e.g. of 32) – Basile Starynkevitch Nov 03 '16 at 15:05
  • Yes We can do that. – King Nov 03 '16 at 15:07
0

First, according to your specifications, max_size should be an unsigned integer, so I changed Vector to reflect this, using size_t. I also changed the related format specifiers from %d to %zu to match this new type.

Your initVector() function needed to allocate memory for a Vector, so that has been added. Furthermore, there was no need to allocate memory for the dynamic array of Data structs here, so v->data is set to NULL. This function should also return the pointer to the newly allocated memory, v, instead of a pointer to the .data field of this Vector, as you originally had.

In the vectorInsert() function, you neglected to check for memory allocation errors, so I added a check after the attempted allocation which returns 0 if there is an error. After inserting the new Data struct, your check to increment .current_size is wrong. First, you need to increment if array->current_size <= index. Next, you need to add one to the .current_size, not set .current_size to one larger than the index value. Also, when printing the inserted value here, you forgot to access the .value field. I think that this may have been due to the confusing name that you used for the Data struct that you passed into vectorInsert(). You call this struct value, so in the previous line we have array->data[index] = value, where you are assigning the struct value to array->data[index]. But in the call to printf() you want to show the value held by the struct value. Choosing better names is always a win! Finally, this function returns 1 on a successful insertion.

I added to your test code to display the contents of vect and vect->data, and also added a Data struct, test_insert, to test insertion into an arbitrary index.

Finally, you need to free memory allocations after all of this, so I added a couple of calls to free().

Here is the code:

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

typedef struct
{
    int value;
}Data;

/* Specs say that max_size should be an unsigned integer */
typedef struct{
    size_t max_size; //initialize to 0
    size_t current_size; //initialize to 0
    Data *data;  // array of integers we're storing
} Vector;

/* Modified function */
Vector * initVector(void){
    Vector *v = malloc(sizeof(*v));
    v->max_size=0;
    v->current_size=0;
    v->data = NULL;
    return v;
}

int  vectorInsert(Vector * array, size_t index, Data value)
{
    if(index >= array->max_size)
    {
        array->max_size = index * 2 + 1; 
        printf("Inside Vect max_size is : %zu\n", array->max_size);

        Data *new_array = malloc(sizeof(Data) * array->max_size);

        /* Added check for allocation error */
        if (new_array == NULL)
            return 0;

        if(array->data != NULL)
        {
            memcpy(new_array, array->data, sizeof(Data)*array->current_size);
            free(array->data);
            array->data = NULL;
        }
        array->data = new_array;
    }

    array->data[index] = value;

    printf("Main : %d\n", array->data[index].value);

    /* Modified current_size increment logic */
    if(array->current_size <= index)
    {
        array->current_size += 1;
    }

    /* Successful insertion */
    return 1;
}

int main(void)
{
    size_t i;
    Vector *vect = initVector();
    Data data_array[20];
    Data test_insert = { -5 };      // to test index insertion

    for(i = 0 ; i < 20 ; i++){
        data_array[i].value = (rand() % 20) + 1;
        vectorInsert(vect, i, data_array[i]);
    }

    /* Display results */
    printf("vect->max_size = %zu\n", vect->max_size);
    printf("vect->current_size = %zu\n", vect->current_size);
    printf("vect->data contains:\n");
    for (i = 0; i < vect->current_size; i++)
        printf("%d ", vect->data[i].value);
    putchar('\n');

    /* Insert test_insert at index 5 */
    vectorInsert(vect, 5, test_insert);

    /* Display results */
    printf("vect->max_size = %zu\n", vect->max_size);
    printf("vect->current_size = %zu\n", vect->current_size);
    printf("vect->data contains:\n");
    for (i = 0; i < vect->current_size; i++)
        printf("%d ", vect->data[i].value);
    putchar('\n');

    /* Free memory allocations */
    free(vect->data);
    free(vect);

    return 0;
}

And here is a sample of the results:

vect->max_size = 31
vect->current_size = 20
vect->data contains:
4 7 18 16 14 16 7 13 10 2 3 8 11 20 4 7 1 7 13 17 

vect->max_size = 31
vect->current_size = 20
vect->data contains:
4 7 18 16 14 -5 7 13 10 2 3 8 11 20 4 7 1 7 13 17 
ad absurdum
  • 19,498
  • 5
  • 37
  • 60