1

I have been trying to make a function, is_isogram, return a value that is an alphabetized string. When I pass the value through the function from main, the variable to be returned is set to the correct value.

However, when I return the variable from the function, it does not return anything in main. Along with this, I get an error for unable to read memory when I initialize the variable to hold the return value in main.

#include <stdbool.h>
#include <ctype.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <Windows.h>
#include "isogram.h"

char  is_isogram(char phrase[])
{
    int i;
    for (i = 0; phrase[i]; i++) {
        tolower(phrase[i]);
    }

    if (phrase == NULL) {
        return false;
    }
    char temp;
    int count1;
    int count2;
    char *alphabet = (char *)malloc(sizeof(char) * (strlen(phrase) + 1));
    int n = strlen(phrase);
    for (count1 = 0; count1 < n - 1; count1++) {
        for (count2 = count1 + 1; count2 < n; count2++) {
            if (phrase[count1] > phrase[count2]) {
                temp = phrase[count1];
                phrase[count1] = phrase[count2];
                phrase[count2] = temp;
                alphabet = phrase;
                break;
            }
        }
    }
    return alphabet;
}

This function does not return the variable alphabet. I have been trying to use malloc and other techniques to return this local variable as a value. I wanted to use every character string as an array with "[]," however I would get errors about needing to initialize an array. The value returned is currently just a sizeable garbage value, however, when I step through the process of debugging, the variable alphabet is 'abb.'

int main() {
    char *bet = is_isogram("bab\0");
    if (bet == 'abb\0') {
        return 0;
    } else {
        return -1;
    }
}

The variable bet is throwing an error before even accessing the function. It tells me it was unable to read the memory and the value for bet is close to NULL for the remainder of the program.

In conclusion, the program is not giving returning a value of 'abb' when from the function locally, nor is it saving the variable in memory. It throws garbage into the variable, but the variable is killed, and a new variable cannot be adequately initialized in main.

15
  • Notice the return type on your function char is_isogram(char phrase[]). if (bet == 'abb\0') is also not going to work. You should be seeing compilation warnings for these things. If not it's time to learn to turn the warning level up. Commented Jul 29, 2018 at 21:59
  • Aside: please note that tolower(phrase[i]); returns a value which you ignore. It does not alter the value passed to it. Try phrase[i] = tolower(phrase[i]); Commented Jul 29, 2018 at 22:02
  • 1
    In alphabet = phrase; you are overwriting the memory pointer that malloc gave you. Don't do that. Commented Jul 29, 2018 at 22:05
  • 1
    sizeof(char) is 1 by definition. The function is_isogram() is declared to return a char, not a char*. The statement alphabet = phrase is almost certainly an error. Commented Jul 29, 2018 at 22:13
  • 1
    Please take notice of compiler warnings. The function char is_isogram(char phrase[]) must return char, yet return alphabet; is returning char *. Commented Jul 29, 2018 at 22:22

1 Answer 1

2

There are multiple problems in your code:

  • Function is_isogram() is defined as returning a char, it should instead return a string, hence type char *.
  • is_isogram() attempts to modify the string pointed to by its argument. Since it is called with a string literal from main, this has undefined behavior, potentially a program crash.
  • You allocate memory for alphabet, but you reset this pointer to phrase in the sorting loop.
  • The comparison bet == 'abb\0' does not do what you think it does. bet should be a char * and you should use strcmp() to compare the string values.

Here is a modified version:

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

char *is_isogram(const char *phrase) {
    char *alphabet;
    int count1, count2, n;

    if (phrase == NULL)
        return NULL;
    alphabet = strdup(phrase);
    n = strlen(alphabet);
    for (count1 = 0; count1 < n; count1++)
        alphabet[count1] = tolower((unsigned char)alphabet[count1]);
    for (count1 = 0; count1 < n - 1; count1++) {
        for (count2 = count1 + 1; count2 < n; count2++) {
            if (alphabet[count1] > alphabet[count2]) {
                char temp = alphabet[count1];
                alphabet[count1] = alphabet[count2];
                alphabet[count2] = temp;
            }
        }
    }
    return alphabet;
}

int main(void) {
    char *bet = is_isogram("bab");
    if (strcmp(bet, "abb") == 0) {
        return 0;
    } else {
        return -1;
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

I get an error when I use this code: Error C2040 'is_isogram': 'char *(const char *) differs in levels of indirection from 'char (char *)'.' When I edit it to have differing levels of indirection and remove asterisks, there are read-write errors. These errors occur because of the indirection in the function declaration char *is_isogram(const char *phrase). Please help me understand why this is happening.
I changed the prototype for char *is_isogram(const char *phrase): it takes a string that it does not modify and returns an allocated copy with the letters sorted alphabetically, or more precisely in lexicographical order. The prototype in isogram.h must be updated accordingly.

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.