0

It seems I'm a bit confused here. As with the use of a pointer to an array of pointers. if I could fetch more info regarding the error, I would have. All I received is a code for a segmentation fault.

a program to find the longest input string.

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

int main()
{
 char **array;
 int i, n, *L, maxlen;


 printf("Enter the number of strings that you wish to store : ");
 scanf("%d", &n);

 array=malloc(n*sizeof(char*)); //acquire storage for an array of pointes of size n//
 L=malloc(sizeof(int)*n);// for the length array//
 for(i=0;i<n;i++)
 {
    printf("Enter string %d : ", i+1); //sometimes, prints upto this//
    gets(array[i]); //sometimes skips the first string input and jumps to the second and stops at the third//
    L[i]=strlength(array[i]);
 }
 maxlen=0;
 for(i=0;i<n;i++)
 {
    if(L[i]>maxlen)
        maxlen=L[i];
 }

  printf("The string(s) with the maximum length with length %d are : ", maxlen);
 for(i=0;i<n;i++)
 {
     if(L[i]==maxlen)
    {
        printf("\n%s.", array[i]);
    }
 }
  return 0;
 }

int strlength(char *array)
{
int j=0;
while(array[j]!='\0')
  {

    j++;
  }
return j;
}
3
  • Use gdb for step-by-step debugging and valgrind for finding memory errors. Commented May 2, 2018 at 18:35
  • 2
    I recommend to remove the part which asks for book/tutorial. That part is off-topic. Instead spend more effort on describing how exactly your program misbehaves, e.g. do some debugging to find the exact line with the segfault. Commented May 2, 2018 at 19:01
  • 1
    The man page for gets even says "Never use gets". Take its advice and use fgets. Commented May 2, 2018 at 19:14

2 Answers 2

1

you allocated memory for pointer to pointer, but forgot to allocate for individual pointers( ie the strings).

it can be modified as,

array=malloc(n*sizeof(char*));

to allocate memory for storing all the pointers for the strings.

and

for( i = 0; i<n; i++)
{
     array[i] = malloc(<max length of string>);
}

then only you will have memory space allocated to store the strings

Sign up to request clarification or add additional context in comments.

1 Comment

The first code example you provide is incorrect. Given array is created as: char **array; in the original post, the line in your answer: *array=malloc(n*sizeof(char*)); will compile and build, but will result in dereferencing a null pointer at run-time. This in turn will crash the program. Remove the *... array=malloc(n*sizeof(char*));. You may have been thinking of using *array rather than the hard type in the malloc statement? eg. array = malloc(n*sizeof(*array)); (this is fine, and in fact preferred)
0

Your memory allocation for:

char **array;
array=malloc(n*sizeof(char*)); //acquire storage for an array of pointes of size n//

only allocates memory for a set of pointers, but none for the space that is needed for the strings the pointers will point to. A function can be defined to encapsulate these steps:

char **array = Create2DStr(numberOfStrings, maxLengthOfString);

Where Create2DStr can be implemented as follows:

char ** Create2DStr(ssize_t numStrings, ssize_t maxStrLen)
{
    int i;
    char **a = {0};
    a = calloc(numStrings, sizeof(char *));// Creates a set of pointers.
    for(i=0;i<numStrings; i++)
    {
      a[i] = calloc(maxStrLen + 1, 1);//creates space for strings pointed to.
    }
    return a;
}

Caution:
- If creating memory in a loop using the same pointer, you should be familiar with realloc()
- maxStrLen in example should contain 1 byte more than the length of the longest string you need to accommodate.
- Do not forget to free everything you created in the reverse order they were created, i.e. free space for strings first (maxStrLen calls to free()), then free the pointers to each string last (1 call to free())). See following example:

free2DStr(&array,numStrings);

The implementation of free2DStr can be done many ways, see below for an example.

void free2DStr(char *** a, ssize_t numStrings)
{
    int i;
    if(!(*a)) return;
    for(i=0;i<numStrings; i++)
    {
        if((*a)[i]) 
        {
            free((*a)[i]);
            (*a)[i] = NULL;
        }
    }
    free((*a));
    (*a) = NULL;
}

Note that in this implementation the address of the object is used in the first argument to provide access to free the pointers residing at that location.

1 Comment

Thanks a lot. your comment cleared a lot of doubts that I had in mind. and thanks for the last part, I almost forgot that I had to free the allocated memory as well. Thanks again <3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.