Iterating and calloc questions.


 
Thread Tools Search this Thread
Top Forums Programming Iterating and calloc questions.
# 1  
Old 08-10-2011
Iterating and calloc questions.

Whilst creating the function readjust_descr I have stumble across what may be a problem or
something that might just work. I was hoping someone could look at the code below and tell me
if readjust_descr will clear all null pointers from the structure descr_list.


Code:
struct descr descr_list = NULL;

  int initialize_descr(int newfd, struct descr *p)
{
    struct descr *d;
    d = descr_list;
    if ( d != 0 ) 
    {
        while ( d->next != 0)
        {
            d = d->next;
        }
    }    
    
    if(!(d->next = malloc( sizeof(struct descr))))
    {
        nonfatal("malloc failure");
        return 0;
    }
    d = d->next;
    d->newfd = newfd;
    d->state = 1;
    d->addr = 0;
    d->next = 0;d = p;
}

int readjust_descr(struct descr *d)
{
    struct descr *l;
    struct descr *r;
    for(l = descr_list; l; l = l->next)
    {
        r = l;
        if (l->state == 0)
        {
            free(l);
            r->next = l->next;
        }
    }
    
}

While I am here I might as well ask this also. Thanks a bunch.

Can you show me how to access the second array of a pointer
that calloc returns if I allocated two elements.
calloc() allocates memory for an array of nmemb elements.

The man page says it returns a pointer to the allocated member.
# 2  
Old 08-10-2011
Quote:
I was hoping someone could look at the code below and tell me if readjust_descr will clear all null pointers from the structure descr_list.
Depends what you mean by that. I believe you're trying to remove elements where state==0, but your attempt may crash frequently, being that it uses the contents of l after it's freed! And does so to no effect anyway, since r is equal to l -- you're just assigning the member to itself.

It would be helpful if you posted your data structures.

calloc doesn't give you 9 individual chunks of memory for one calloc of 9 elements, it gives you one big chunk large enough to hold 9 elements. You access further elements the same way you'd use any other array -- arrays just being locations in memory too.

Code:
char *arr=(char *)calloc(9, sizeof(char));
arr[0]='a';
arr[1]='b';
arr[2]='c';

// pointer to second element
char *second = arr+1;
(*second)='z';

# 3  
Old 08-11-2011
Here is the data chunk.

So if I put the free(i) statement afterwards it will work?

Code:
struct descr *descr_list = 0;

struct descr
{
    int newfd;         /* Send and receive from newfd */
    short int state;   /* State of player in the game */
    char request[7024];
    struct descr *next;/* For generating a list */
};


Last edited by Errigour; 08-11-2011 at 01:10 PM..
# 4  
Old 08-11-2011
Quote:
Originally Posted by Errigour
So if I put the free(i) statement afterwards it will work?
You're still assigning the same thing to itself so your code makes no sense in any order.
# 5  
Old 08-11-2011
Thanks for looking at it. I'm just now fixing some of these problems but I'm still
getting a problem after I fixed some of this stuff to.

---------- Post updated at 01:45 PM ---------- Previous update was at 01:31 PM ----------

Bah I'm reading up on gdb atm and it's helping alittle bit.
Anyone know how to get this to work?
Code:
printf("                sin_family: %d\n", inco.sin_family);

also here's the updated function initialize descr, I made some changes to it, the old one had only
one error that I can see.
Code:
int initialize_descr(int newfd, struct descr *p)
{
    struct descr *d;
    d = descr_list;
    if ( d != 0 ) 
    {
        while ( d->next != 0)
        {
            d = d->next;
        }
    }    
    
    if(!(d = malloc( sizeof(struct descr))))
    {
        nonfatal("malloc failure");
        return 0;
    }
    d->newfd = newfd;
    d->state = 1;p = d;
}

on the first one I had used d=p; which was completly dumb.
# 6  
Old 08-11-2011
Quote:
Originally Posted by Errigour
also here's the updated function initialize descr, I made some changes to it, the old one had only one error that I can see.

Code:
int initialize_descr(int newfd, struct descr *p)
{
    struct descr *d;
    d = descr_list;
    if ( d != 0 ) 
    {
        while ( d->next != 0)
        {
            d = d->next;
        }
    }    
    
    if(!(d = malloc( sizeof(struct descr))))
    {
        nonfatal("malloc failure");
        return 0;
    }
    d->newfd = newfd;
    d->state = 1;p = d;
}

on the first one I had used d=p; which was completly dumb.
You check if equal to 0. They're pointers, why not use NULL? Also you check for d->next but you don't initalize d->next. Here is an old function I wrote with linked lists...

Code:
void queue_add(char *buf)
{
        struct s_queue *newq, *q;

        /* fixme: error checking */
        newq = malloc(sizeof(struct s_queue));
        newq->next = NULL;

        newq->line = malloc(strlen(buf) + 1);
        strcpy(newq->line, buf);

        /* insert it */
        if (!queue_head)
                queue_head = newq;
        else {
                /* find last one */
                for (q = queue_head; q->next; q = q->next) ;
                q->next = newq;
        }
}

# 7  
Old 08-12-2011
Network I can't print stuff I want to!!

I'm having another problem with this function. I can't print the line below. I receive
a segmentation fault at line one using gdb. I'f I modify that line from d->newfd to
newfd (which is a variable that is equal to what d->newfd should be) it works just fine.
Then if I uncomment the lines below that are commented I get an error, Program
received signal SIGINT, Interrupt. The new function that I posted seems to be
working and I can use d->state and d->newfd with FD_ISSET and as a comparison
for state checking other wise everything seems to work and I haven't run into any
other problems yet.

Code:
printf("New connection: on socket %d,\n", d->newfd);
printf("                sin_addr:   %s", inet_ntoa(inco.sin_addr));
/*
printf("                sin_family: %s\n", inco.sin_family);
printf("                sin_port:   %s\n", inco.sin_port);
printf("                s_addr:     %s\n", inco.sin_addr.s_addr);
printf("                sin_zero:   %s\n", inco.sin_zero[8]);*/

Code:
int initialize_descr(int newfd, struct descr *p)
{
    struct descr *d;
    d = descr_list;
    //malloc(sizeof(struct descr))
    if( d != 0)
    {
        while(d->next != 0)
            d = d->next;
        if(!(d->next = malloc(sizeof(struct descr))))
            nonfatal("malloc failure initializing descr");
        d = d->next;
    }
    else
        if(!(d = malloc(sizeof(struct descr))))
            nonfatal("malloc failure initializing descr");
    d->newfd = newfd;
    d->state = 1;p = d;
    return sizeof(p);
}

This is the entire program that works.
Code:
/**************************************************************************\
 * Type          * Bits*byte* Possible Values                             *
 **************************************************************************
 * short         * 16  *2   * -32768 to 65536                             *
 * unsigned short* 16  *2   * 0 to 65536                                  *
 *               *     *    *                                             *
 * int           * 32  *4   * -2147483648 to 4294967295                   *
 * long          * 32  *4   * -2147483648 to 4294967295                   *
 * unsigned int  * 32  *4   * 0 to 4294967295                             *
 * long long     * 64  *8   * -9223372036854778838 to 18446744073709551616*
 **************************************************************************
 * char      long      float     volatile                                 *
 * short     signed    double    void                                     *
 * int       unsigned  const                                              *
 *                                                                        *
 * char, signed char, unsigned char                                       *
 * int, signed int, unsigned int                                          *
 * short int, signed short int, unsigned short int                        *
 * long int, signed long int, unsigned long int                           *
 * float, double, long double                                             *
\**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include "server.h"
#include "constants.h"
#include "math.h"

struct descr *descr_list = NULL;

struct descr
{
    int newfd;                /* Send and receive from newfd */
    short int state;          /* State of player in the game */
    struct descr *next;       /* For generating a list */
    struct input_queue *queue;/* Character input queue */
};

int initialize_descr(int newfd, struct descr *p)
{
    struct descr *d;
    d = descr_list;
    //malloc(sizeof(struct descr))
    if( d != 0)
    {
        while(d->next != 0)
            d = d->next;
        if(!(d->next = malloc(sizeof(struct descr))))
            nonfatal("malloc failure initializing descr");
        d = d->next;
    }
    else
        if(!(d = malloc(sizeof(struct descr))))
            nonfatal("malloc failure initializing descr");
    d->newfd = newfd;
    d->state = 1;p = d;
    return sizeof(p);
}

struct input_queue 
{ 
    char ch_input[7024];      /* Character input in queue */
    struct input_queue *next; /* Queued input or null     */
};

int readjust_descr(struct descr *d)
{
    struct descr *l;
    struct descr *r;
    for(l = descr_list; l; l = l->next)
    {
        r = l;
        if (l->state == 0)
        {
            r->next = l->next;
            free(l);
        }
    }
    return sizeof(d);    
}

char character_login(struct descr *d)
{
    int rbytes = 0;
    const char er[] = "Character name is to large.\r\n\r\n";
    const char ln[] = "\r\nCharacter name or (n)ew: ";
    if ((rbytes = recv(d->newfd, d->queue->ch_input, 12, 0)) <= 0)
    {
        if (rbytes == 0)
            printf("Socket %d hung up\n", d->newfd);
        else
            nonfatal("Receiving a file descriptor");
        d->state = 0;
    }
    
    if (rbytes > 11)
    {
        send(d->newfd, er, sizeof er, 0);
        send(d->newfd, ln, sizeof ln, 0);
    }
    else
        d->state = 2;
}

int main()
{    
    struct sockaddr_in serv;
    struct sockaddr_in inco;
    struct timeval seconds;
    socklen_t inclen;
    int simpleSocket;
    int clientSocket;
    int yes = 1;
    int fdmax;        // maximum file descriptor number
    int newfd;

    fd_set master;    // master file descriptor list
    fd_set read_fds;  // will be watched to see if characters become available for reading
    fd_set write_fds;  // will be watched to see if a write will not block
    fd_set except_fds; // will be watched for exceptions.

    seconds.tv_sec  = 0;      /* seconds for select to wait for connections     */
    seconds.tv_usec = 1000;   /* microseconds for select to wait for connections
                               * there are 1,000 microseconds in a millisecond
                               * there are 1,000 milliseconds in a second     
                               * thus there are 1,000,000 Microseconds in one 
                               * second, and there are 60 seconds in one minute */

    printf("Process id #%i\n", getpid());
    FD_ZERO(&master);    // clear the master and temp sets
    FD_ZERO(&read_fds);
    FD_ZERO(&write_fds);
    FD_ZERO(&except_fds);

    if ((simpleSocket=socket(AF_INET, SOCK_STREAM,0)) == -1)
    {
        fatal("Creating simpleSocket, AF_INET SOCK_STREAM failed");
    }
    fcntl(simpleSocket, F_SETFL, O_NONBLOCK); 
    setsockopt(simpleSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
  /*struct sockaddr_in
    {
        short   sin_family; /* must be AF_INET
        u_short sin_port;
        struct  in_addr sin_addr;
        char    sin_zero[8]; /* Not used, must be zero
    };
    struct in_addr { int s_addr; }; */
    serv.sin_family = AF_INET;
    serv.sin_addr.s_addr = INADDR_ANY;
    serv.sin_port = htons(2000);

    if (bind(simpleSocket,(struct sockaddr *)&serv,sizeof(serv)) == -1)
    {
        close(simpleSocket);
        fatal("Binding simpleSocket, AF_INET SOCK_STREAM failed");
    }

    if (listen(simpleSocket, 1000) == -1) 
    {
        close(simpleSocket);
        fatal("Listening to simpleSocket, AF_INET SOCK_STREAM failed");
    }

    // add the listener to the master set
    FD_SET(simpleSocket, &master);

    // keep track of the biggest file descriptor
    fdmax = simpleSocket; // so far, it's this one

    for(;;)
    {
        struct descr *d;
        int i;
        
        read_fds = master;
        write_fds = master;
        except_fds = master;

        if (select(fdmax+1, &read_fds, &write_fds, &except_fds, &seconds) == -1)
            nonfatal("Select failed");
        if (FD_ISSET(simpleSocket, &read_fds))
        {
            /* handle new connections */
            newfd = accept(simpleSocket, (struct sockaddr *)&inco, &inclen);
            if(newfd == -1)
                nonfatal("Accepting a file descriptor");
            else 
            {
                FD_SET(newfd, &master); /* add to master set */
                if (newfd > fdmax)      /* keep track of the max */
                      fdmax = newfd;
                int i = GetRand(0, 4);
                send(newfd, castle_well[i], sizeof (castle_well[i]), 0);
                const char name_prompt[] = "Character name or (n)ew: ";
                send(newfd, name_prompt, sizeof name_prompt, 0);
                initialize_descr(newfd, d);
                printf("New connection: on socket %d,\r\n", newfd);
                printf("                sin_addr:   %s\r\n", inet_ntoa(inco.sin_addr));
                /*
                printf("                sin_family: %s\n", inco.sin_family);
                printf("                sin_port:   %s\n", inco.sin_port);
                printf("                s_addr:     %s\n", inco.sin_addr.s_addr);
                printf("                sin_zero:   %s\n", inco.sin_zero[8]);*/
            }
        } /* END FD_ISSET(simpleSocket, &read_fds) */
        
        for (d = descr_list; d; d = d->next)
        {
            if(FD_ISSET(d->newfd, &read_fds) && d->state == 1)
                character_login(d);
        }
        for(i = 0; i<1000; i++)
            if(!(i%1000))
            {
                        int j;
                        const char tick[] = "tick.";
                        for(j = 0; j <= fdmax; j++) 
                        {
                            // send to everyone!
                            if (FD_ISSET(j, &master)) 
                            {
                                send(j, tick, sizeof tick, 0);
                            }
                        }
            }
    }/* END for(;;).*/
    close(simpleSocket);
    exit(EXIT_SUCCESS);
}

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Question on iterating array elements

Hi, I am trying to do something similar to the for loop example from KSH For Loop Array: Iterate Through Array Values $: cat y.ksh #!/bin/ksh # set array called nameservers set -A nameservers 192.168.1.1 192.168.1.5 202.54.1.5 # print all name servers for i in ${nameservers} do ... (3 Replies)
Discussion started by: newbie_01
3 Replies

2. Shell Programming and Scripting

Iterating awk over a directory of files?

I need to run the same awk function over an entire directly of files. This is the awk: awk '{$(NF+1)=1}1' Is there a way that I can run this command once over all of the files, along the lines of: awk '{$(NF+1)=1}1' * so that I do not have to run this several times? My main concern is... (2 Replies)
Discussion started by: owwow14
2 Replies

3. Programming

calloc fails: 'Cannot allocate memory'

Hi , experts. I work on Linux station (RedHat 5.7), regular user, but have root password. %> uname -a Linux ran1log06 2.6.18-238.1.1.el5 #1 SMP Tue Jan 4 13:32:19 EST 2011 x86_64 x86_64 x86_64 GNU/Linux %> cat /etc/issue Red Hat Enterprise Linux Client release 5.7 (Tikanga) Kernel \r on... (5 Replies)
Discussion started by: baruchgu
5 Replies

4. Shell Programming and Scripting

Iterating over a list using awk, when variable

Hi, I've recently started using Awk commands as i need it to pull information out of a file and give me the mean value of a series of numbers. Here is the code i run on my Infile and it works just fine. awk '{if ($1 == "Mam189") print $0}' Infile | awk '{if ($1 != $2) print $0}' | awk... (5 Replies)
Discussion started by: cavanac2
5 Replies

5. Shell Programming and Scripting

Iterating over subdirectories and dealing with files within them

Hello, I am working on a coding project for a class and to test the program I have created, I have come up with 100 different test cases. The program takes four text files as input, so each of the test cases is contained in a folder with four files. I have a folder called 'tests', within which... (1 Reply)
Discussion started by: dpryor
1 Replies

6. Programming

Calloc C++

Hello all, I have a confusion with calloc function : wz. the difference between the following 2 statemnts: char *ptr; char = (char*)calloc(num, sizeof(char)); char = (char*)calloc(num, sizeof(char*)); Am really confused!!!!! ---------- Post updated at 09:32 AM... (1 Reply)
Discussion started by: mind@work
1 Replies

7. Shell Programming and Scripting

Iterating through two arrays in a single loop

Hey everyone. Is it possible to use two arrays in a loop? Basically what I am trying to do is iterate through the elements in an array, and, based on a condition, use the current position in the array to point to that index in the array. Here's the loop structure I'm looking for: ... (1 Reply)
Discussion started by: msarro
1 Replies

8. Shell Programming and Scripting

iterating over results from sqlplus

hi all, i am writing a ksh script, i am logging into an oracle db via sqlplus and running a select statement but i dont know how i can store the results from the sql so i can iterate over it and do more operations over it. I dont want to write a stored procedure with a cursor since i need to... (2 Replies)
Discussion started by: cesarNZ
2 Replies

9. Shell Programming and Scripting

Problem iterating in while loop

I am facing a problem in replacing the file contents by iterating through the list. My present code: Code: #!/bin/bash# TFILE="/tmp/vinay/testb_1.txt" while read linedo aline="$line" echo $aline code=`echo $aline|cut -d ',' -f1` country=`echo $aline|cut -d... (5 Replies)
Discussion started by: av_vinay
5 Replies

10. UNIX for Advanced & Expert Users

memset vs calloc

Dear Friends, Can any one tell me the difference between memset and calloc function in C. Regards, Selvi (7 Replies)
Discussion started by: salvi
7 Replies
Login or Register to Ask a Question