We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now


arrays of pointers to pointers

swright243 asked
Medium Priority
Last Modified: 2010-04-15
I am a Pascal programmer learning C. To help me I am converting
programs I have written to C. My editor uses an array of
pointers to strings to make it possible to edit text files
larger than 64K. I can do it in Pascal, but I am having
trouble figuring out how to make an array of pointers to
strings. Here's the code so far, it compiles, but will not
load files more than a two or three lines long.

//LED project conversion from Turbo Pascal
//May 7, 1997 Stephen E. Wright, PhD
//This version is a only text file viewer for large files
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

const MaxCharPerLine=1024;       /*max string length*/
const MaxLines=16000;            /*max number of lines*/
const PageSize=25;               /*PC screen height in lines*/

FILE *inputf;                    /*file to read*/
char file_name[79];              /*name of file to read*/
char string[MaxCharPerLine];     /*define a string*/
char *s = string;                /*pointer to a string*/
typedef char** str;              /*pointer to a pointer to a char*/
typedef str tLines[MaxLines];    /*define an array of above*/
tLines *t;

int keystroke, arrowkey;         /*used to identify keys pressed*/
unsigned int i, j, k;            /*counters*/
unsigned int MaxLineNumber;      /*number of lines read */

enum boolean {FALSE, TRUE};      /*simulate Pascal "boolean"*/
boolean ESCpressed, ScrChanged;  /*flags*/

void LoadTheFile(void)
   /*open a text file for reading*/
   do {
      puts("File: ");
      if ((inputf = fopen(file_name, "rt") ) == NULL )
       printf("Error in file name : '%s'\n", file_name);
   } while (inputf==NULL);

   /*get memory for array of pointers to strings*/
   t = (tLines*) malloc(MaxLines * sizeof(*s));
   for (i=0; i<MaxLines; i++, *t[i]=NULL);

   /*read file and copy lines to memory */
   j = 0;
   while (!feof(inputf))
      fgets(s, MaxCharPerLine, inputf);
      *t[j] = (char**) malloc(strlen(s)+1);
      strcpy(**t[j], s);
   /* if (last line does not end with newline) */
   if (s[strlen(string)-1] != 10) j++;

void EnterText(void)
   int refreshCounter;
   int Topline;

   Topline = 1;

   while (!ESCpressed)
      if (ScrChanged) /*update display*/

         if (PageSize > MaxLineNumber)               /*just one page*/
         if (MaxLineNumber-PageSize < Topline)       /*last page*/
         else refreshCounter=Topline+PageSize-1;     /*all other pages*/

         /*note that screen coords out of sync with array coords*/
         for ( j=Topline-1; j<refreshCounter-1; j++)
            strcpy(s, **t[j]);
            printf("%s", s);

      keystroke=getch();                       /*get a keystroke*/
      if (keystroke == 0) arrowkey = getch();  /*extended key pressed*/

      switch (keystroke)
         case 27: ESCpressed=TRUE; break; /*ESC pressed*/
         case 0:
            switch (arrowkey)
               case 81:                  /*PgDn*/
                  if (MaxLineNumber<PageSize)
                     Topline = 1;
                     if ( (Topline+(2*PageSize)-1) < MaxLineNumber )
                        Topline = Topline+PageSize-1;
                        Topline = MaxLineNumber-PageSize+1;

               case 73:                  /*PgUp*/
                  if (Topline-PageSize < 1)
            } /*switch arrowkey*/
         break; /*case 0: */
         default: break;  /*do nothing with any other key pressed*/
      } /*switch keystroke*/
   } /*while !EndofFile */

int main(void)
   return 0;
Watch Question

Youre code is a mess! While browsing I noticed several errors. I strongly advice you to buy a GOOD book. The best I've ever read is "The C Programming Language" by Kernighan and Ritchie
I will give some pointer examples here:
int a;     // an int
int *b;    // a pointer to int
int c[3];  // an array of int's
int **d;   // a pointer to a pointer of int;
int *e[2]; // an array of int pointers

b = c;   // Yes c is in fact an pointer to int.
a = *b;  // assign the thing wich points to to a
b = &a;  // assign the adress of a (a pointer) to b
b = (int*)malloc(3*sizeof(int)); // create a array of int dynamically
d = e;   // Yes e is in fact an pointer to a pointer to int
b = *d;  // Right... (*d) is a pointer to int (just as b)
b = *e;  // Again, in fact b is now the first element of the array e
b = e[0]; // Exacly the same as b = *e;

Let me give you an example of how it should be done:
First: a character string is a array of chars, so it's type is: char *
Second: a array of strings is {a array of (strings)} is a {array (of arrays of char)} is {a array of (char *)} is {(char *)* }

So a array of strings should be:
char **arrayOfStrings;
char **arrayOfStrings;
// first lets allocate space for the array of strings
arrayOfStrings = (char **)malloc(NOLINES * sizeof(char *));
// initialize array
for (int i = 0; i < NOLINES; i++) arrayOfString[i] = NULL;

// second lets read in every line
char buffer[256];
while (fgets(buffer, 255, in))
  // strdup allocates space for the string AND copies the buffer
  // into it.
  arrayOfStrings[i] = strdup(buffer);

// Do what you have to with the arrayOfStrings

// cleanup
for (int i = 0; i < NOLINES; i++)
  if (arrayOfStrings[i] != NULL) free(arrayOfStrings[i]);

Now lets look at the most SEVERE errors in you code
First the declaration nightmare:

typedef char** str; /*pointer to a pointer to a char*/
typedef str tLines[MaxLines]; /*define an array of above*/
tLines *t;

Ok so str is a char ** (an array of char* = array of strings)
What's tLines ?? it's an array of str, wich is an array of char ** so it's an char ***. And t is  a pointer to such a thing. So its in fact a char **** (could be: an array of an array of an array of array of chars (What a file browser THIS is gonna be, a superdimensional one! ;) )
The bottomline is: don't use typedefs on these simple structures, it makes things more complicated, especially if you're a beginner.

Second: your allocation:

/*get memory for array of pointers to strings*/
t = (tLines*) malloc(MaxLines * sizeof(*s));

In fact you have to use malloc like this:
Type *t = (Type*) malloc(N *sizeof(Type));

But you use sizeof(*s), and (*s) is not of type tLines but of char !! In fact you allocate MaxLines bytes, but you should allocate MaxLines*4 bytes (MaxLines pointers). This is certainly gonna crash.
Also is the tLines not a type for an array of strings, but I explained that before.

// AAAAAAAAARGHHHH what's this:
*t[j] = (char**) malloc(strlen(s)+1);
strcpy(**t[j], s); // <- Crashhhhh :(

first you allocate space strlen(s)+1 bytes. You cast this to char** So in fact you using your space for pointers to char*
(youre making an array of char*). But the type you cast to an the sizecalculation in malloc are out of sinc. It should always be:
(Type*)malloc(no * sizeof(Type)). I guess you fiddled with your program until the compiler stopped complaining ;)

Well I hope I helped you a little, but I strongly advice you to buy Kernighan an Ritchie (believe me it's the best) before trying to code any further.

Good Luck, Luc

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.