user3572494
user3572494

Reputation: 41

Error: return makes pointer from integer

I was trying to make a function which will scan strings and create one dimension array of strings.

While compiling I have got this error:

return makes pointer from integer without a cast

The code of this function is here:

char **insert_strings(int *n) {
    char **strings;
    char *string;
    strings=(char **)malloc((*n)*sizeof(char*));
    for(int i=0;i<(*n);i++)
        strings[i]=(char*)malloc(30*sizeof(char));
    for(int i=0;i<(*n);i++) {
        scanf("%s",string);
        strcpy(strings[i],string);
    }
    return **strings;
}

Upvotes: 2

Views: 1714

Answers (5)

Teo Zec
Teo Zec

Reputation: 381

Your function is decleared to return a pointer to pointer to char, but you are returning just a char.

This confusion is caused because the * unary operator can have two meanings:

  • Inside of variables and functions definitions, * means: "this variable (or this function) is a pointer". Therefore, char **insert_strings(int *n) returns a pointer to a pointer to char, and char **strings is a pointer to a pointer to char.

  • Outside of definitions, instead, the unary * operator is the deferencing operator, and *a means: "the object that is at the location indicated by the value of a".

    Let's say that we have this situation in the computer memory:

    Addresses   1  |  2  |  3  |  4  |  5  |  6
    Values      5  |  3  |  6  |  9  |  2  |  9
    

    If, for example, the address of the variable strings (which is defined in your code) is 5, its value is 2. So, the value of *strings is the value at location 2, which is 3. **strings is the value at the location pointed by *strings. The value of *strings is 3, so the value of **strings is 6.


That been said, I'll explain you why you get the error: insert_strings() should return the value of a pointer to pointer to char, which in your code is the value of strings (2 in our example), but you are returning the value of **strings (6 in our example), which is a char and not a pointer.

To fix your code, you should just change

return **strings;

to

return strings;

There are some other problems with your code that don't lead to compile-time errors, but must be corrected because they will likely lead to run-time errors.

  1. n shouldn't be a pointer. It is counting the number of string you are going to input, so it should just be an int.
  2. You should never, never, NEVER! use scanf() to get input strings; I'll explain you why. In your program, you allocate space for 30 chars to your variable string. Now, what will happen if someone inputs more than 30 characters? If you are lucky, the program will just terminate. If you are not, it can crash later, and you won't know where to find the bug. The solution is to use fgets(char *s, int size, FILE *stream). This function is safe because you can tell it how many characters the user can input. In your example, you would use it as follows: fgets(string, 30, stdin);

Eventually, I would like to suggest you a couple of things to make your program better:

  1. Check the return value of malloc(), and don't cast it: it's useless and redundant. (See Deduplicator's comment to your question for more information).
  2. sizeof(char) is always equal to 1. It's useless to write it.
  3. Use just the strings variable: you don't need also the string variabile, you can do well without it.
  4. Use a pointer to array instead of a pointer to pointer. You know the dimension of a string in advance, you don't need to dinamically allocate it.

Accordingly to what I said, your code should be something like:

#include <stdio.h>     /* Needed for fgets()  */
#include <stdlib.h>    /* Needed for malloc() */

/* char **insert_strings(int n)
 * Gets n strings from input and puts them inside an array of strings.
 * Arguments: n is the number of lines that will be got from input.
 * Return value: the array of strings, or NULL if it couldn't be allocated. */
char **insert_strings(int n)
{
    /* strings is a pointer to array */
    char (*strings)[30];

    if((strings = malloc(n)) == NULL)
        return NULL;

    /* The loop that gets the input.
     * We use fgets() because it's safe.
     * 30 is the number of characters that we can get for every string.
     * stdin is the standard input, which is usually the keyboard. */
    for (int i = 0; i < n; i++)
        fgets(strings[i], 30, stdin);

    return strings;
}

Upvotes: 2

Lee Duhem
Lee Duhem

Reputation: 15121

According to the context, there is no need to dereference that strings, you should use return strings;.

Upvotes: 2

AzeemSheikh
AzeemSheikh

Reputation: 67

Why to return **Strings when you have already taken it as (char **)? return only String. that will be sufficient.

Upvotes: 0

William Pursell
William Pursell

Reputation: 212208

Return strings instead of **strings. **strings is a char.

Upvotes: 4

George Nechifor
George Nechifor

Reputation: 439

you should have return strings; (without **). Then everything should be ok.

Upvotes: 0

Related Questions