簡體   English   中英

使用struct進行段錯誤

[英]Seg fault using struct

我已經寫了大約一個星期了,所以請耐心等待。 我在方法assemble_url遇到了分段錯誤錯誤,我不知道為什么。 這是我的代碼:

/** Includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>

/** Definitions */
#define MAX_OPTIONS 32
#define MAX_ARGS 32

/** Command option */
typedef struct {
    char *argname;
    char *value;
} command_option;

/** Command */
typedef struct {
    command_option options[MAX_OPTIONS];
} command_t;

/**
 * Prints the arguments passed in in a hashmap format (key => value)
 */
void populate_command(command_t *cmd,int argc,char *argv[])
{
    int i,j=0;

    /** Check to see if we have arguments. If argc is equal to 1 than there are no arguments besides the filename */
    if(argc>1)
    {

        /* Start at position 1, since argv[0] is the filename being called */
        for(i=1;i<argc;i++)
        {

            /* Head of argv array */
            char *arg = argv[i];

            /* Create a copy of head for traversal. */
            char *c = arg;

            /* traverse the char array, ensuring we arent dealing with NULL values(c!==NULL) and NULL pointers(*c!=='\0') */
            while(*c != '\0' && c != NULL)
            {

                /* Were only concerned with parsing the flags and obtaining the flag value. */
                if(strchr("-",*c))
                {

                    char *key = c; /* Key */
                    char *value = argv[i+1]; /* Value */

                    /* ensure we have a value existent for key */
                    if(strchr("-",*value))
                    {
                        /** user supplied a key with no value */
                        break;
                    }
                    command_option *option = &cmd->options[j];
                    option->argname = key;
                    option->value   = value;

                    j++;

                    /* Debug dump */
                    printf("arg %d: %s -> %s\n",i,option->argname,option->value);

                }/* end strchr */

                /** Increment the traversal array */
                c++;

            }/* end while loop */

        }/* end forloop */

    }/* endif */

}/** end print_args */

/**
 * Concatenates two strings and returns the resulting concatenated string
 */
char* concatstring(char *s1,char *s2)
{
    /* Allocate memory for *result. We add 1 to account for the extra byte to store the null character. Strlen accounts for all
     non-null bytes, so using strlen(s1) + strlen(s2) + 1 ensures that an overflow wont occur. An overflow occurs when
     the number of bytes being used (in our example, is the addition of strlen for s1 and s2) is more than the number of bytes
     allocated (in our example, the number of bytes allocated to *result)*/
    char *result = malloc(strlen(s1)+strlen(s2)+1);

    /*Copies the C string pointed by source(s1) into the array pointed by destination(result), including the terminating null character. */
    strcpy(result,s1);

    /* appends a copy of the source string(s2) to the destination string(result). The terminating null character in
     destination is overwritten by the first character of source, and a null-character is included at
     the end of the new string formed by the concatenation of both in destination.*/
    strcat(result,s2);

    /* return result */
    return result;

} /** end concatstring */

char* assemble_url(command_t *cmd,char *str)
{
    int i,opt_len = sizeof(&cmd->options);
    for(i=0;i<opt_len;i++)
    {
        command_option *option = &cmd->options[i];
        char *key = option->argname;
        char *value = option->value;
        if(i==0)
        {
            str = concatstring(str,key);
            str = concatstring(str,"=");
            str = concatstring(str,value);
        }
        else
        {
            str = concatstring(str,"&");
            str = concatstring(str,key);
            str = concatstring(str,"=");
            str = concatstring(str,value);
        }
    }
    return str;
}

該計划中發生的情況如下:

1. /用戶輸入程序名稱和標志選項,如下所示: program -test a -test2 b

2. /程序解析命令並使用選項填充命令結構。 每個選項都有一個標志(argname)和與之關聯的值(值)

3. /程序然后嘗試使用這些選項鍵和值創建URL,例如http://url/?test=a&test2=b

程序編譯,但我仍然是指針和引用的新手(我認為&稱為參考),所以也許這就是程序錯誤的原因。

任何幫助是極大的贊賞! 另外,如果你看到任何探測器或更好的方法來處理assemble_url,也請讓我知道(我不認為它以最好的方式處理,但就像我說的,我是C編程的新手)

謝謝!

這個初始化

int opt_len = sizeof(&cmd->options);

將為您提供指針&cmd->options的字節大小。 在你想要做的事情的背景下,這沒有任何意義。

如果你想確定數組中元素的數量(假設它沒有衰減到指針),那么正確的技術就是

int opt_len = sizeof cmd->options / sizeof *cmd->options;

在這種情況下, opt_len將使用MAX_OPTIONS值進行初始化(這意味着您可以在其位置使用MAX_OPTIONS )。

你有來自concatstring的大量內存泄漏。 每次調用都會分配一個新的緩沖區,但你永遠不會費心去釋放它們,並且你松開了指針,所以沒有機會再次釋放那個內存。

這不是段錯誤的原因。

因為你連接了兩個以上的字符串,所以最好一次為所有連接分配內存。

#include <stdarg.h>
#include <string>
char* stringBuilder(int count, ...)
{
    va_list ap, vacnt;
    int j;
    int len = 1;
    char* buffer;
    va_start(ap, count); 
#ifdef va_copy
        va_copy(vacnt,ap);
#else
    vacnt = ap;
#endif
    for(j=0; j<count; ++j){
        len+=strlen(va_arg(vacnt, char*)); 
    }
    va_end(vacnt);
    buffer = (char*) malloc(len * sizeof(char));
    buffer[0]=0;
    for (j=0;j<count;++j) {
       strcat (buffer, va_arg(ap, char*));
    }
    va_end(ap);
    return buffer;
 }

您可以這樣使用它:

char* x = stringBuilder(4,"hello", " ", "world", "\n");
printf(x);
free(x);

另請注意,為了您的應用程序,鍵和值必須是URL編碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM