Home > Mobile >  initialization of 'const char **' from incompatible pointer type 'char *'
initialization of 'const char **' from incompatible pointer type 'char *'

Time:05-15

I am new in learning C. I have an issue in returning double star pointer from the function.

This is my code.

#include <stdio.h>
#include <stdbool.h>

#include "api.h"

void init() {
  // You can initiate and calculate things here
}

/**
 * Return the given list in reversed order. Each element in the given list contains a single character.
 * 
 * typedef struct {
 *   int count;
 *   const char * * elements;
 * } string_list;
 * 
 * list_of_chars: string_list
 * 
 * returns: string_list
 */
string_list reverse(string_list list_of_chars) {
  // Write your code here
  char X[list_of_chars.count];
  
  //X[0] = *list_of_chars.elements[0];
  
  for (int i = 0; i < list_of_chars.count;i  ){
  X[i] = *list_of_chars.elements[i];
  }
  printf("%c", X[0]);

  string_list return_value = {
    .count = 0,
    .elements = &X[0],
  };
  return return_value;
}

But I am getting initialization of 'const char **' from incompatible pointer type 'char *'. I tried multiple solutions but non of them worked.

CodePudding user response:

Side note: As I mentioned in the top comments, I was limited to what I could do on mobile. I'm back at my desk.

Issues were:

  1. X is function scoped, so it goes out of scope when the function returns. We need to use malloc [so we need stdlib.h]
  2. Because elements is a const char **, then we need const char **X

We need to use [should use] strdup to duplicate the elements.

Otherwise, both lists will share the same data. This may the desired intent. But, it's not clear from the problem description what the correct code should be.

Most lists should be fully independent from one another. The original code does not do this. So, the lists are sharing the data. But, if that's true, why bother to create a separate list? We could just "reverse" it by indexing in the reverse direction without creating a new list:

for (int i = list.count - 1;  i >= 0;  --i)

So, I've chosen to duplicate the strings. Original behavior (shared strings) when compiled with -DNODUP.

Here's the refactored code:

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

#if 0
#include "api.h"
#else
typedef struct {
    int count;
    const char **elements;
} string_list;
#endif

void
init()
{
    // You can initiate and calculate things here
}

/**
 * Return the given list in reversed order. Each element in the given list contains a single character.
 *
 * typedef struct {
 *   int count;
 *   const char * * elements;
 * } string_list;
 *
 * list_of_chars: string_list
 *
 * returns: string_list
 */
string_list
reverse(string_list list)
{
    const char **X = malloc(sizeof(*X) * list.count);

    // share the strings
#if NODUP
    for (int i = 0; i < list.count; i  )
        X[list.count - 1 - i] = list.elements[i];

    // make lists independent (more usual/expected)
#else
    for (int i = 0; i < list.count; i  )
        X[list.count - 1 - i] = strdup(list.elements[i]);
#endif

    string_list ret = {
        .count = list.count,
        .elements = X,
    };

    return ret;
}

UPDATE:

In the link above was the exercise page where we can choose GCC for C. I pasted your code exactly to the website bit still see same errors.

Okay, finally ... ;-)

  1. The website uses an ancient version of the C standard (e.g. C99). This does not have strdup.
  2. The website will [forcibly] do a #include "api.h" before including the code, so there is a conflict with the definition I used.

Here is the corrected code (which runs successfully on the website):

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

#if 1
#include "api.h"
#else
typedef struct {
    int count;
    const char **elements;
} string_list;
#endif

void
init()
{
    // You can initiate and calculate things here
}

/**
 * Return the given list in reversed order. Each element in the given list contains a single character.
 *
 * typedef struct {
 *   int count;
 *   const char * * elements;
 * } string_list;
 *
 * list_of_chars: string_list
 *
 * returns: string_list
 */
string_list
reverse(string_list list)
{
    const char **X = malloc(sizeof(*X) * list.count);

    // share the strings
#if 1
    for (int i = 0; i < list.count; i  )
        X[list.count - 1 - i] = list.elements[i];

    // make lists independent (more usual/expected)
#else
    for (int i = 0; i < list.count; i  )
        X[list.count - 1 - i] = strdup(list.elements[i]);
#endif

    string_list ret = {
        .count = list.count,
        .elements = X,
    };

    return ret;
}

Side note: I'd get a good book on C and study that to get more basic knowledge of C. Trying to use "competition" websites isn't the best way, IMO.

A number of the issues you've seen (but did not understand) would have been obvious with a better basic understanding of C syntax and semantics.

Here's a list: The Definitive C Book Guide and List

  • Related