-1

Writing a program in C and I am trying to pass two variables into the function kstrextend. Name which is a word or set of characters that is stored in the value kstring and a which is a numeric value, but name is not getting passed into the function at all as far as I can tell and I cannot figure out why. Is something not getting stored correctly? Because the function works just fine I just cannot get name passed in correctly.

Declaration of kstring and name:

kstring name;
char kstring[50]; 

Typedef:

typedef struct
    {
        char *data;
        size_t length;
    } kstring;

Function:

void kstrextend(kstring *strp, size_t nbytes)
{
    char *nwData;
    int lnth=strp->length;
    if(lnth < nbytes)
    {
        // new array allocate with large size and copy data to new array
        nwData = (char *)realloc(strp->data, nbytes);
        // call abort in case of error
        if(nwData == NULL)
        {
            abort();
        }
        //Making strp->data point to the new array
        strp->data = nwData;
        //Setting strp->length to the new size.
        strp->length = nbytes;
        for(int i = 0; i <= lnth; i++)
        {
            printf("\n %s",strp->data);
        }
        // filled with '\0' in remaining space of new array
        for (int lp = lnth; lp < nbytes; lp++)
        {
            strp->data[lp] = '\0';
            printf("\n %s", strp->data[lp]);
        }
    }
}

Portion of main:

    size_t a;
    char * k = kstring;
    printf("\n Enter number: ");
    scanf("%d", &a);
    name.data = (char*)calloc(sizeof(k), 1);
    strcpy(input, k);
    name.length= kstring_length;
    kstrextend(&name,a);
  • `sizeof(k)` is the size of the *pointer*, not the lenght of whatever string you want. Also arrays decays to pointer to their first element, so the temporary variable `k` is not needed. And don't forget that if you use `strlen` to get the actual length of the string, it will not include the terminator. And of course, in C you [should not cast the result of `malloc`, `callor`, `realloc` or similar functions](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Some programmer dude Feb 05 '19 at 06:53
  • The correct format for reading a `size_t` like `a` is `%zu`. You might get away with using `%d` on a 32-bit system, but that's thin ice. – Jonathan Leffler Feb 05 '19 at 06:53
  • 1
    The rest of the little code you show also seem off, so please try to create a [mcve] to show us, one that only exhibits the problem you're asking about (without any irrelevant errors or warnings). If the problem is that you get build errors (or warnings) then include them verbatim in full and complete (copy-pasted as text). And please read about [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Feb 05 '19 at 06:55
  • Please show the code you compile — an MCVE or [MCVE]. While you can probably sequence the code shown so that it compiles (if the `typedef` is at file scope before the two definitions shown previously, and the definitions are in function scope), it probably doesn't do what you expect. – Jonathan Leffler Feb 05 '19 at 06:56
  • If I see correctly, `kstring` is data type and variable name? Call `kstrextend` with `kstrextend( name.data, a );`. Other problems are answered above. – i486 Feb 05 '19 at 13:36

1 Answers1

1

First of all, you have misleading variable name kstring. Use something else like kstring_init and assign it a value. I assume you want to initialize the name variable of type kstring with something and then change its length. So this is what it is all about. Then define a constant of type char * and initialize length and data of your kstring with it. Then use realloc to extend the memory of the pointer with the input value a, not with the size of k. That does not make sense. Since the size of k is the size of the pointer, which is constant.

In your function: don't use int if you pass size_t. Use the same datatype where you do the same things.

In your loop from 0 to lnth, you output the same string lnth+1 times, which does not make sense. You probably want to output the characters of the string. So use %c and use an index into the character array and don't set <= lnth but < lnth as upper limit. Take care with data types if signed and unsigned!

Design hint: If you have a if block, that wraps all your code... invert the condition and just exit so that the code is after the if block.

Take care when you work with size_t and int, since int is signed and size_t is not, which can give problems in if statements.

Don't use abort but rather exit. You don't want your program to abort abnormally and core-dump.

A working version of your program is:

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

typedef struct
    {
        char *data;
        size_t length;
    } kstring;

kstring name;
char *kstring_init = "blabla";

void kstrextend(kstring *strp, size_t nbytes)
{
    char *nwData;

    size_t lnth = strp->length;

    if ((int) lnth >= (int) nbytes) {
        printf("Error, size already larger than requested size.\n");
        exit(-1);
    }

    // new array allocate with large size and copy data to new array
    nwData = realloc(strp->data, sizeof(char) * (int) nbytes);
    if(nwData == NULL)
    {
        printf("Error, realloc returned NULL\n");
        exit(-1);
    }

    //Making strp->data point to the new array
    strp->data = nwData;
    //Setting strp->length to the new size.
    strp->length = nbytes;

    for(int i = 0; i < lnth; i++)
    {
        printf("\n %c", strp->data[i]);
    }
    // filled with '\0' in remaining space of new array
    for (int lp = lnth; lp < (int) nbytes; lp++)
    {
        strp->data[lp] = '\0';
        printf("\n %c", strp->data[lp]);
    }
}

int main(void)
{
    size_t a;

    printf("\n Enter number: ");
    scanf("%d", &a);

    name.length = strlen(kstring_init) + 1;
    printf("Length of string is: %d\n", name.length);
    name.data = (char*)malloc(sizeof(char) * name.length);
    strcpy(name.data, kstring_init);

    printf("Old string: %s\n", name.data);
    printf("You want to reallocate %d bytes\n", a);

    kstrextend(&name, a);

    return 0;
}
andi8086
  • 394
  • 2
  • 9