aanrv
aanrv

Reputation: 2241

Issue accessing contents of array of character pointers in C

I am going through The C Programming Language by K&R and trying to understand character pointers and arrays.

I am creating a function in C that reads multiple lines from stdin and stores the lines (char*) in an array of character pointers (char* []).

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

enum {MAXINPUT = 1024, MAXLINES = 100};

/* Reads at most `maxLines` lines and stores them in an array of char pointers. Returns number of lines read. */
int readlines(char* lineptr[], int maxLines);

/* Takes a single line input from stdin and stores it in str. Returns str length. */
int getInputLine(char* str, int maxInput);

int main(int argc, char** argv) { ... }

int readlines(char* lineptr[], int maxLines) {
    /* Return number of lines read. */
    int numLines = 0;
    /* Buffer to store current line being read. */
    char currentLine[MAXINPUT];

    /* Terminate loop when enter is pressed at empty input or number of lines exceeds max. */
    while(getInputLine(currentLine,MAXINPUT) && numLines < maxLines) {
        /* Address of current line's first character is set to the appropriate index at lineptr. */
        lineptr[numLines] = currentLine;

        /* Both currentLine and lineptr[numLines] print accurately (note they are the same). */
        printf("CURRENT LINE:\t %s\n",currentLine);
        printf("lineptr[%d]:\t %s\n",numLines,lineptr[numLines]);

        numLines++;
    }

    /* ISSUE: Outside the loop, lineptr does NOT print anything. */
    printf("\nLOOPING\n");
    for(int i = 0; i < numLines; i++) {
        printf("%d: %s\n",i,lineptr[i]);
    }

    /* ISSUE: currentLine (which should be the last line entered) ALSO does not print outside the while. */
    printf("\ncurrentLine: %s",currentLine);

    return numLines;
}

My issue is that in the while(), the contents of lineptr and currentLine print accurately. But outside the while(), both lineptr and currentLine do not print anything.

And of course, this issue persists when I try to read lines into a char* [] in the main() and try to print its contents.

Why is it that the contents at the addresses being accessed by lineptr are printing inside the loop but not outside? Am I missing something obvious?

Upvotes: 0

Views: 72

Answers (2)

R Sahu
R Sahu

Reputation: 206567

This line

    lineptr[numLines] = currentLine;

just assigns a pointer to lineptr[numLines]. There are couple of issues with that:

  1. Every line points to the same pointer.
  2. The pointer is invalid after you return from the function.

You need to use something akin to:

    lineptr[numLines] = strdup(currentLine);

Remember that strdup is not a standard C library function. If your platform does not support it, you can implement it very easily.

char* strdup(char const* in)
{
    char* ret = malloc(strlen(in)+1);
    return strcpy(ret, in);
}

Upvotes: 1

Mike Nakis
Mike Nakis

Reputation: 61969

That's because you have a single buffer called currentLine into which you read text. Then you assign the address of currentLine to your lineptr[i], and proceed to overwrite its contents with new text. So, all your lineptrs essentially point to the same one location, which is the address of currentLine, and currentLine contains only the last line that you read. I suppose the loop does not print anything because the last line you read is empty.

So, to get this to work, you need to read a line into currentLine, measure its length, use malloc() to allocate enough memory for that line, copy the line from currentLine to the allocated memory, and store the pointer to the allocated memory in lineptr[i].

Upvotes: 2

Related Questions