Thread: Dynamic Memory Allocation Problems

  1. #1
    Registered User
    Join Date
    Jun 2015
    Posts
    19

    Dynamic Memory Allocation Problems

    Good evening all! I am currently in the middle of a program for my class and have run into quite an odd issue... Essentially, our program is supposed to create a word search algorithm that goes through a puzzle and searches for words horizontally, vertically, and diagonally (backwards and forwards).
    Everything was going fine - I had created two of my functions, one of which dynamically allocates a sufficient amount of space for the words in a given dictionary and populates an array of strings, and another which dynamically allocates space for the word search grid and populates it - until I got to the function for reversing the strings.
    I know how to create a function that reverses the order of a string (and I am also aware of strrev; however, for our program we are not to use strrev). I will provide the code below this paragraph and explain what the issue is after the code in order to make the question succinct.

    Code:
    int stringManipulation(const char *word) {
        int i, j, len;
        char* backwards;
    
    
        len = strlen(word);
        
        backwards = malloc(sizeof(char)*len + 1);
    
    
        printf("%d\n", len);
    
    
        for(i = 0, j = (len - 1); i < len && j >= 0; i++, j--) {
            backwards[i] = word[j];
        }
        
        printf("size of backwards = %d, string length = %d, word in backwards: %s\n", sizeof(backwards), strlen(backwards), backwards);
        
        return 1; 
    }
    Everything runs fine... Except for the dynamic memory allocation portion. The word I am passing into my function is the second word in my sample dictionary, "be", which has a length of 2. My printf statement verifies that. However, when I print strlen(len) it prints 2, when I print sizeof(backwards) it prints 4, when I print strlen(backwards) it prints 8, and when I print the word in backwards it prints eb (backwards of "be") plus some other bs (since I only have it reading in values to the first two elements in the array). I have tried re-writing the malloc statement as malloc(sizeof(char)*500), malloc(5000), malloc(len), etc. No matter what I do, the numbers I provided above all remain the same.
    I feel like I am making some huge noob mistake, but I am at my wit's end with this problem, haha. Any tips or advice would honestly be greatly appreciated

  2. #2
    Registered User Ktulu's Avatar
    Join Date
    Oct 2006
    Posts
    107
    I don't see why you need to use malloc.

    Code:
    void strman( char* word )
    {
    
        char* lpword;
    
        char temp;
    
        unsigned int len,
                     rindex;
    
    
        lpword = word;
    
        len = rindex = strlen( word );
    
        while ( rindex-- > len / 2 )
        {
            temp = *word;
    
            *word++ = *(lpword + rindex);
    
            *(lpword + rindex) = temp;
        }
    
        *(lpword + len) = '\0';
    
        return;
    }
    Last edited by Ktulu; 09-21-2015 at 06:29 PM.
    This parameter is reserved

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by Ktulu View Post
    I don't see why you need to use malloc.
    Depends on where word comes from. I notice that the original version of stringManipulation had const char * as the type of the first argument. That is a type compatible with string literals. Yet your version is different, and actually takes away this feature. Calling strman is not safe if word is a string literal. The resulting behavior is undefined.

  4. #4
    Registered User
    Join Date
    Jun 2015
    Posts
    19
    Hey, I'm sorry, I should have been more specific about the purpose of my function.
    The reason that I am using malloc is that I want to keep the list of backward words once I exit back into main.

  5. #5
    Registered User
    Join Date
    Jun 2015
    Posts
    19
    I'm reading the words in from a dynamically allocated 2D array of words

  6. #6
    Registered User Ktulu's Avatar
    Join Date
    Oct 2006
    Posts
    107
    Yes you are right, you should use strman as shown below when using string literals.

    Code:
    char* word = "something";
    
    unsigned int len = strlen( word );
    
    char* revword = malloc( sizeof(char) * len + 1 );
    
    strcpy( revword, word );
    
    strman( revword );
    This parameter is reserved

  7. #7
    Registered User FourAngels's Avatar
    Join Date
    Aug 2015
    Location
    Canada
    Posts
    130
    Quote Originally Posted by Andres Posadas View Post
    Good evening all! I am currently in the middle of a program for my class and have run into quite an odd issue...

    Code:
    char * stringManipulation(const char *word) {
        int i, j, len;
        char* backwards;
        len = strlen(word); 
        backwards = malloc(sizeof(char)*len + 1);
    
        for(i = 0, j = len ; i <= len; ) {
            backwards[i++] = word[j--];
        }
        backwards[i] = '\0'
    
        return backwards; 
    }
    Try something more simple, unless I misunderstood the question!.... no compiler on hand to test the code.

  8. #8
    Registered User
    Join Date
    Jun 2010
    Posts
    24
    Quote Originally Posted by Andres Posadas View Post
    when I print strlen(backwards) it prints 8, and when I print the word in backwards it prints eb (backwards of "be") plus some other bs (since I only have it reading in values to the first two elements in the array).
    sizeof(backwards) gives you the size of a char pointer, not the length of a string. Strings are terminated with a null character which is what strlen() will be looking for when it calculates the length so you need this at the end of your word in backwards.
    Last edited by Golf7; 09-22-2015 at 07:32 AM.

  9. #9
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Andres Posadas View Post
    Code:
    backwards = malloc(sizeof(char)*len + 1);
    should be:

    Code:
    backwards = malloc(sizeof(char)*(len + 1));
    The difference is that in your code, due to operator precedence, it adds one byte to the amount allocated, when it should add sizeof(char), because sizeof(char) might be greater than one byte.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  10. #10
    Registered User
    Join Date
    Jun 2010
    Posts
    24
    The standard requires sizeof(char) to be one.
    Last edited by Golf7; 09-22-2015 at 08:24 AM.

  11. #11
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    Quote Originally Posted by Golf7 View Post
    The standard requires sizeof(char) to be one.
    Incorrect.

    Quote Originally Posted by C11 Standard 6.2.5
    An object declared as type char is large enough to store any member of the basic
    execution character set. If a member of the basic execution character set is stored in a
    char object, its value is guaranteed to be nonnegative. If any other character is stored in
    a char object, the resulting value is implementation-defined but shall be within the range
    of values that can be represented in that type.
    I see absolutely no reference to exactly one byte.
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Elkvis
    I see absolutely no reference to exactly one byte.
    That is because you looked in the wrong place:
    Quote Originally Posted by C11 Clause 6.5.3.4 Paragraph 4a
    When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I see absolutely no reference to exactly one byte.
    Perhaps you're looking at the wrong section of the standard.

    6.5.3.4 The sizeof and alignof operators
    Constraints

    1. The sizeof operator shall not be applied to an expression that has function type or an
    incomplete type, to the parenthesized name of such a type, or to an expression that
    designates a bit-field member. The alignof operator shall not be applied to a function
    type or an incomplete type.

    Semantics

    2. The sizeof operator yields the size (in bytes) of its operand, which may be an
    expression or the parenthesized name of a type. The size is determined from the type of
    the operand. The result is an integer. If the type of the operand is a variable length array
    type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an
    integer constant.

    3. The alignof operator yields the alignment requirement of its operand type. The result
    is an integer constant. When applied to an array type, the result is the alignment
    requirement of the element type.

    4. When sizeof is applied to an operand that has type char, unsigned char, or
    signed char, (or a qualified version thereof) the result is 1.
    When applied to an
    operand that has array type, the result is the total number of bytes in the array.102) When
    applied to an operand that has structure or union type, the result is the total number of
    bytes in such an object, including internal and trailing padding.
    Jim

  14. #14
    Registered User
    Join Date
    Jun 2015
    Posts
    19
    First, I want to thank everyone for taking the time to respond to my question

    With that being said, I know that sizeof doesn't print the string length, but strlen does. The issue is that, no matter what I set the malloc function to, when I print out the numbers they are all the same - regardless of the malloc statement. D:

  15. #15
    Registered User
    Join Date
    Jun 2015
    Posts
    19
    Quote Originally Posted by Elkvis View Post
    should be:

    Code:
    backwards = malloc(sizeof(char)*(len + 1));
    The difference is that in your code, due to operator precedence, it adds one byte to the amount allocated, when it should add sizeof(char), because sizeof(char) might be greater than one byte.
    I have tried this as well, and the results are all the same. I have tried compiling and running the code on DEVC++, Codeblocks, and on a Linux system, and I get the same result over and over :/

    *EDIT: sizeof(backwards) always results in 8, strlen(backwards) always results in 3, but strlen(word) is always 2 (the correct size of the word).
    Last edited by Andres Posadas; 09-22-2015 at 09:07 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamic Memory Allocation
    By slash.hack in forum C Programming
    Replies: 9
    Last Post: 09-30-2011, 04:31 AM
  2. Memory dynamic allocation
    By elvio.vicosa in forum C Programming
    Replies: 8
    Last Post: 10-16-2007, 03:30 AM
  3. Dynamic memory allocation.
    By HAssan in forum C Programming
    Replies: 3
    Last Post: 09-07-2006, 05:04 PM
  4. Dynamic memory allocation...
    By dicorr in forum C Programming
    Replies: 1
    Last Post: 06-24-2006, 03:59 AM
  5. dynamic memory allocation
    By inquisitive in forum C++ Programming
    Replies: 5
    Last Post: 03-13-2004, 02:07 AM