【问题标题】:Return a pointer of an array of pointers返回一个指针数组的指针
【发布时间】:2013-11-04 22:46:19
【问题描述】:

编辑:解决方案可能在页面底部。我用解决方案回答了我的问题。我希望这对其他人有所帮助。

我在 linux 中遇到了一个小问题。我正在编写一个简单的端口扫描,但我遇到了接受参数的函数的问题。

我会在代码上解释:

#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 数组中。 像这个字符: "指向包含字符数组的该数组的字符指针"

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

在这种情况下,“指针指针”将是字符串的第一个字符。

总结:我想创建一个字符串数组并将其从arguments_handle返回给main函数。

有什么想法吗? :)

此致,

int3

【问题讨论】:

  • 您正在访问超出数组边界的ret,导致未定义的行为。
  • 我认为你的 strcpy 是问题所在。看Mysticial发布的答案

标签: c arrays pointers segmentation-fault malloc


【解决方案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;
}

【讨论】:

  • +1 表示getopt,-1 表示strncpy。简单地将argv[i] 分配给const char *hostnameconst char *portrange 更容易。
  • 真的吗? malloc? strlen? strncpy?跳过所有的杂乱无章并使用std::string
  • @Captain Obvlious 我正在编程 C 而不是 C++。 :) 没有命名空间 eheh
  • @int3 如果您希望得到仅 C 的答案,请不要标记您的问题 C++。
  • 我已经更新了我的答案。我希望它是有用的。 @RolandIllig,是的,你是对的。这是最简单的解决方案,我在我的代码示例中使用过。感谢您的建议。
【解决方案2】:

我解决了这个问题!

非常感谢朱塞佩佩斯! 我不习惯 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

【讨论】:

    猜你喜欢
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 2021-06-25
    • 1970-01-01
    相关资源
    最近更新 更多