2013-11-04 252 views
0

編輯:解決方案也許是在頁面的底部。我用解決方案回答了我的問題。我希望這可以幫助其他人。返回指針數組的指針

我在這裏有一個小問題。我正在編程一個簡單的端口掃描,但我遇到了帶參數的函數的問題。

我將在代碼解釋:

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <arpa/inet.h> 
#include <stdlib.h> 
#include <string.h> 

//this function handle the arguments. 

char* ret[2]= {"NULL","NULL"}; //declaring this in global because of segmention fault? 

char** arguments_handle(int argc,char **arg) 
{ 
    if(argc!=5) 
    { 
     printf("Usage:./file -p PORT-RAGE -h HOST.IP\n"); 
     exit(1); 
    } 
    //make sure the user type the correct arguments. in this case just -h and -p 
    if(strcmp(arg[1],"-p")==0 || strcmp(arg[1],"-h")==0 && strcmp(arg[3],"-p")==0 || strcmp(arg[3],"-h")==0) 
    { 
     //if in the arguments we got -h or -p run this 
     //if is -p 
     if(strcmp(arg[1],"-p")==0) 
     { 
      //take the next argument in this case is the port range and put in our array 
      strcpy(ret[0],arg[2]); 
     } 
     else 
     { 
      strcpy(ret[1],arg[2]); 
     } 
     if(strcmp(arg[3],"-h")==0) 
     { 
      //now for the -h 
      strcpy(ret[1],arg[4]); 
     } 
     else 
     { 
      strcpy(ret[0],arg[4]); 
     } 
    } 
    return ret; 
} 
int main(int argc, char **argv) 
{ 
    char** ipnport; 
    ipnport = arguments_handle(argc,argv); 
    printf("IP is :%s port range is %s\n",ipnport[0],ipnport[1]); 
    //the rest of the code about port scan goes here. I'm just cutting 
    return 0x0; 
} 

這裏的問題是,我可以編譯正確的,但我得到了分段故障。我看不到我錯在哪裏。我想這是關於緩衝區或堆棧溢出的處理。

所以我在這裏做的這個函數是採取argv並將其發送到arguments_handle函數。 這樣做是看到參數「-p」和「-h」以及「存儲」在char數組中的正確順序。 喜歡此CHAR: 「字符指針到該數組包含字符數組」

    pointer  pointer pointer 
pointer to this-> ["firstarg","secondarg","etc"] 

在這種情況下,「指針的指針的指針」將字符串的第一個字符。

總結:我想創建一個字符串數組,並將其從arguments_handle返回給main函數。

任何想法? :)

真誠,

INT3

+0

你訪問'ret'超出導致不確定的行爲數組的邊界。 –

+0

我認爲你的strcpy是問題所在。看看[Mysticial]發佈的答案(http://stackoverflow.com/questions/8716714/bus-error-10-error) –

回答

1

的問題是,你是不是分配給你的命令行得到的字符串正確的內存空間。

char* ret[2]= {"NULL","NULL"}; 

這將創建一個數組,其中包含兩個大小爲4的字符串+結束字符('\ 0')。這是你想要的嗎?或者你想創建兩個NULL指針。 如果輸入字符串的大小大於4,會發生什麼情況?您可能會訪問導致分段錯誤的錯誤內存。另外,您不應該使用strcpystrcmp,而是使用strncpystrncmp

代碼應該是變化如下:

char * ret[2]; 

    if(strncmp(arg[3],"-h", 3)==0) 
    { 
     string_size = strlen(arg[4]) + 1; 
     ret[1]= malloc(sting_size); 
     memset(ret[1], 0, string_size); 
     strncpy(ret[1],arg[4], string_size); 
     // or ret[1]=arg[4] as suggested by Roland 
    } 

然而,有沒有需要編寫輸入參數的解析器功能getopt可以實現這個要求。這是一個很好的例子手動結尾:http://man7.org/linux/man-pages/man3/getopt.3.html

一個簡單的例子爲您的代碼:

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <arpa/inet.h> 
#include <stdlib.h> 
#include <string.h> 
#include <getopt.h> 

#define NUMBER_ARGUMENTS 2 
#define IP 1 
#define PORT 0 

char* ret[NUMBER_ARGUMENTS]; 

int main(int argc, char **argv) 
{ 
    int opt; 

    while ((opt = getopt(argc, argv, "p:h:")) != -1) { 
       switch (opt) { 
       case 'p': 
        ret[PORT]=optarg; 
        break; 
       case 'h': 
        ret[IP]=optarg; 
        break; 
       default: /* '?' */ 
        fprintf(stderr, "Usage: %s -p PORT -h HOST\n", 
          argv[0]); 
        exit(EXIT_FAILURE); 
       } 
    } 
    printf("IP is :%s port range is %s\n",ret[IP],ret[PORT]); 
    //the rest of the code about port scan goes here. I'm just cutting 
    return 0x0; 
} 
+0

提到'getopt'爲+1,'strncpy'爲-1。簡單地將'argv [i]'分配給'const char * hostname'和'const char * portrange'會更容易。 –

+0

真的嗎? 'malloc'? 'strlen'? 'strncpy'?跳過所有的crud並使用'std :: string'。 –

+0

@Captain Obvlious我正在編程C而不是C++。 :)沒有命名空間eheh – int3

0

我解決了這個問題!

非常感謝Giuseppe Pes! 我不習慣malloc和memset和東西。 但是,這解決了這個問題。我知道這是試圖把數據,其中它不應該:d

這是我的最終代碼:

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <arpa/inet.h> 
#include <stdlib.h> 
#include <string.h> 

//this function handle the arguments. 

//well i didnt edit strcpy and strcmp to strncpy yet but I will :D 

char* ret[2]; //GLOBAL ofc. 

char** arguments_handle(int argc,char **arg) 
{ 
    if(argc!=5) 
    { 
     printf("Usage:./file -p PORT-RAGE -h HOST.IP\n"); 
     exit(1); 
    } 
    //make sure the user type the correct arguments. in this case just -h and -p 
    if(strcmp(arg[1],"-p")==0 || strcmp(arg[1],"-h")==0 && strcmp(arg[3],"-p")==0 || strcmp(arg[3],"-h")==0) 
    { 
     //if in the arguments we got -h or -p run this 
     //if is -p 
     if(strcmp(arg[1],"-p")==0) 
     { 
      //take the next argument in this case is the port range and put in our array 
      strcpy(ret[0],arg[2]); 
     } 
     else 
     { 
      strcpy(ret[1],arg[2]); 
     } 
     if(strcmp(arg[3],"-h")==0) 
     { 
      //now for the -h 
      strcpy(ret[1],arg[4]); 
     } 
     else 
     { 
      strcpy(ret[0],arg[4]); 
     } 
    } 
    return ret; 
} 
int main(int argc, char **argv) 
{ 
    //tested on windows we need to put a cast before malloc 
    //in linux it works fine on my raspberrypi !! :D 
    ret[0] = (char*)malloc(20); //some compilers maybe will throw here an error 
    ret[1] = (char*)malloc(20); //because malloc returns a void pointer and ret is a char* 

    memset(ret[0],0,20); 
    memset(ret[1],0,20); 

    char** ipnport; 
    ipnport = arguments_handle(argc,argv); 
    printf("IP is :%s port range is %s\n",ipnport[1],ipnport[0]); 
    //the rest of the code about port scan goes here. I'm just cutting 
    return 0x0; 
} 

再次感謝,我希望這段代碼可以幫助一些人看到這個帖子:)

真誠,

INT3