Thread: error subscripted value is neither an array nor pointer nor vector

  1. #31
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    546
    Cause he either forgot and had non-compiling code or simply is a bad programmer talking out of his ..........

  2. #32
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    too be fair there were lots of oh hang on no it works like this statements as he was explaining it but it did compile. anyway my code works now i need to impliment your other suggeston and have a function that gets the data from the user then assigns it in one lump.
    coop
    Last edited by cooper1200; 05-24-2019 at 11:04 AM.

  3. #33
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    546
    Quote Originally Posted by cooper1200 View Post
    too be fair there were lots of oh hang on no it works like this statements as he was explaining it but it did compile. anyway my code works now i need to impliment your other suggeston and have a function that gets the data from the user then assigns it in one lump.
    coop
    From the console scanf is the solution like in my above example, just use &tmp.VALUE for each expected value you put in the format parameter to use that right, for GUI I would suggest something like Tefaf's (I think that was the name) IUP Library

  4. #34
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    ok now whats up all i have done is switch the inputting of data to a separate function.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct Address
    {
        int door_number;
        char *street;
        char *city;
        struct Address *next;
    }Address;
    
    void add_address(Address **first, Address **current);
    Address get_address_details(void);
    void print_list(Address *first);
    void delete_list(Address **first);
    
    int main()
    {
        Address *first = NULL, *current = NULL;
    
        add_address(&first, &current);
        add_address(&first, &current);
        add_address(&first, &current);
        //add_address(first, current);
        //add_address(first, current);
    
        print_list(first);
        delete_list(&first);
    
        return 0;
    }
    
    void add_address(Address **first, Address **current)
    {
        Address *p_new_element, temp;
    
        //get a new block of memmory and test the pointer isnt null
        p_new_element = malloc(sizeof(Address));
        if (!p_new_element)
        {
            printf("memmory allocation error");
            return;
        }
    
        temp = get_address_details();
        p_new_element = &temp;
        printf("door = %d street = %s city = %s\n", temp.door_number, temp.street, temp.city);
        printf("door = %d street = %s city = %s\n", p_new_element->door_number, p_new_element->street,
                                                                                   p_new_element->city);
        if (*first == NULL) // no list yet so make p_new_element the head
        {
            *first = p_new_element;
            (*first)->next = NULL;
            *current = *first;
            return;
        }
        if ((*first)->next == NULL) //only one element in the list
        {
            (*first)->next = p_new_element;
            *current = p_new_element;
            (*current)->next = NULL;
            return;
        }
        //more than 2 elements
        (*current)->next = p_new_element;
        *current = p_new_element;
        (*current)->next = NULL;
    }
    
    Address get_address_details(void)
    {
        char my_str[20];
        Address tmp;
    
        //get door number and assign it to the new elements member 'door_number'
        printf("Please enter the door number: ");
        scanf(" %d", &tmp.door_number);
    
        //get street name and assign it to my_str
        printf("Please enter street name: ");
        scanf(" %s", my_str);
        //create memory for the street name and assign the pointer address->street to point to it
        tmp.street = malloc(strlen(my_str) + 1);
        if (!tmp.street)
        {
            printf("error in getting memmory for street name");
            //return;
        }
        //copy contents of my_str into the memmory location pointed to by address->street
        strcpy(tmp.street, my_str);
    
        //get city name
        printf("Please enter city name: ");
        scanf(" %s", my_str);
        //create memory for the city name and assign the pointer address->city to point to it
        tmp.city = malloc(strlen(my_str) + 1);
        if (!tmp.city)
        {
            printf("error in getting memmory for city name");
            //return;
        }
        //copy contents of my_str into the memmory location pointed to by address->city
        strcpy(tmp.city, my_str);
    
        return tmp;
    }
    
    void print_list(Address *first)
    {
        int count = 1;
        Address *temp = first;
    
        while (temp)
        {
            printf("address no %d is door number %d street %s city %s\n", count, temp->door_number,
                                                                           temp->street, temp->city);
            count++;
            temp = temp->next;
        }
    }
    
    void delete_list(Address **first)
    {
        int count = 1;
        Address *temp = NULL;
    
        printf("freeing memmory....\n");
        while (*first)
        {
            temp = (*first)->next; // set temp to point at the next element in the list
            printf("freeing element %d's street name\n", count);
            free((*first)->street); //free the memmory block that holds firsts street name
            printf("freeing element %d's city name\n", count);
            free((*first)->city); //free the memmory block that holds firsts city name
            printf("freeing struct %d's memmory\n", count);
            free(*first); //free the memmory block that holds the first element
            (*first) = temp; // set first to point at the next memmory block;
            count++;
        }
        printf("finished freeing all allocated memmory\n");
    }
    it compiles and the two printf statements after assigning temp to the pointer display the info correctly as entered. but once i hit the print function it never breaks out and prints a lot of rubbish to the screen
    coop

  5. #35
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    546
    For starters set temp to 0 like this:
    Code:
     Address temp = {0};
    when initialising l, second NEVER give a pointer to a stack variable to a pointer value being returned, at work so few opportunities to respond, and have short replies, I'll take another look when I get a chance

  6. #36
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    546
    Sorry meant tmp in get_address_details(), still don't have time to do thorough check of your code however look at when you fill the "next" parameter and make sure the it's the previous address that recieves the pointer and don't tamper with the tmp one

  7. #37
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    ok god knows how this is happening and what the hell has caused it but it appears that when setting the head of the list the first->next doesn't get set to null; therefor the second if doesnt get run. and all other nodes are set on current so nothing is linked and there is no null to terminate the print loop.

  8. #38
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    546
    You got a memory leak in add_address()

  9. #39
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    546
    Here's an example of handing those pointers information
    Code:
    *p_new_address = get_address_details();
    if ( p_prv_address) p_prv_address->next = p_new_address;

  10. #40
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    546
    Also you should allocate all memory you're going to use BEFORE asking the user for their details

  11. #41
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    ok im not getting this.... i have done nothing other than move the data entry into another function and yet it suddenly changes how the program operates ie it doesn't work. the only call to malloc in add_address gets the lump of memory for the new node. i would of thought i need that until i call delete list and if i try to free it at the end of the function i get double free or corruption (out)
    Aborted (core dumped)

    Process returned 134 (0x86) execution time : 7.599 s
    Press ENTER to continue.

    i just don't understand how something that appears to work as far as the printf's in get address show suddenly stops a previously working section of code working.

    coop

  12. #42
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    ok thanks for that it all works now.

  13. #43
    Registered User
    Join Date
    Apr 2019
    Posts
    662
    Quote Originally Posted by awsdert View Post
    Also you should allocate all memory you're going to use BEFORE asking the user for their details
    i dont know what the user is going to input it might be the full 20 characters or might just be 5 should i malloc for the full 20 then use realloc to reduce it to the size required?

  14. #44
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    546
    Yep, from a user standpoint we don't want to give our details only to find an error message saying not enough memory, we just wasted our time as a result, better to give a smoother experience by saying not enough memory from the get go and skipping the message if we got the memory and just continuing normally

  15. #45
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,066
    Quote Originally Posted by awsdert View Post
    Drop the count + 1 and leave just count in there, also initialise count to 1, if the allocation fails the decrement it, 9 times out of 10 you'll never reach the decrement and save yourself an operation when repeating this say 1000 times
    While I agree with your analysis, I think that also misses the forest for the trees: cooper1200's example reallocates every time an element is inserted to the dynamic array. This potentially means quadratic time complexity if realloc somehow isn't able to expand the dynamic array in-place for a sufficiently large number of insertions (whereas a single additional addition on each insertion doesn't change the time complexity at all, and is a relatively small penalty in practice). Avoiding this requires more work, e.g., keeping track of both size and capacity and having a suitable reallocation strategy, so it isn't quite as simple as cooper1200 believes it to be (although it doesn't have to be too complicated either).

    Quote Originally Posted by cooper1200 View Post
    thanks.... is this bad programming practice then??? why have the facility of linked lists if a thicko like me can come up with a simple way round them
    Try inserting into a dynamic array at the front. You'll find that it takes linear time. Try inserting into a linked list at the front. You'll find that it takes constant time. Linked list wins this round!

    Given a pointer to somewhere in the middle of a dynamic array, try inserting an element after it. You'll find that it takes linear time. Given a pointer to a node in the middle of a linked list, try inserting an element after it. You'll find that it takes constant time. Linked list wins this round!

    Given a pointer to somewhere in the middle of a dynamic array, try removing that element. If you want the removal to be stable, you'll find that it takes linear time. Try removing the next element in a linked list given a pointer to a node in the middle. You'll find that it takes constant time while maintaining stability. Linked list wins this round!

    Try removing all the elements of a dynamic array that matches some criteria. If you implement a naive algorithm, you'll find that this takes quadratic time, whereas the obvious algorithm for a linked list takes linear time. You can implement a linear time algorithm to do this for a dynamic array, but it is more complex. Linked list wins this round!

    You want to sort items fast while maintaining stability, so you implement a merge sort with a dynamic array. You find that it takes O(n) auxiliary space. You switch to using a linked list. You find that it takes O(1) auxiliary space. Linked list wins this round!

    Of course, I have cherry picked examples in which linked lists have an advantage over dynamic arrays. I could also have cherry picked other examples in which dynamic arrays have an advantage over linked lists. So, as awsdert pointed out, "there are cases for it (...) but yes it doesn't fit everything". (Note that "such as trees" is incorrect: while linked lists can be seen as degraded trees, the use cases for trees differ from those of linked lists because there are ways to avoid such degradation, e.g., by using balanced binary trees.)

    Click_here gave you good advice in post #19 that you seem to be ignoring (besides ignoring what I told you about naming conventions in post #22):
    Quote Originally Posted by Click_here
    Make another struct that keeps track of the list
    Now, keeping track of the count has its pros and cons: it can mean extra work for little return if you rarely need the count, and for some operations it can change a constant time complexity to a linear time complexity because you may have to recount. However, it makes it much easier when you have both head and tail pointers, e.g.,
    Code:
    struct AddressList
    {
        struct Address *head;
        struct Address *tail;
    };
    
    void add_address(AddressList *addresses)
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Subscripted value is neither array nor pointer ?
    By prietito1 in forum C Programming
    Replies: 2
    Last Post: 08-08-2012, 12:42 AM
  2. subscripted value is neither array nor pointer: 2 files
    By pochis40 in forum C Programming
    Replies: 6
    Last Post: 05-27-2011, 03:16 PM
  3. Replies: 1
    Last Post: 05-08-2010, 10:03 PM
  4. Replies: 9
    Last Post: 03-16-2009, 02:18 AM
  5. subscripted value is neither array nor pointer
    By new_to_c in forum C Programming
    Replies: 8
    Last Post: 04-01-2007, 02:43 PM

Tags for this Thread