简体   繁体   English

为什么这两个char *变量的值在退出函数后没有更改?

[英]Why are the values of these 2 char* variables didn't change after exit the function?

I'm populating a C program to multiply 2 input vectors. 我正在填充一个C程序来乘以2个输入向量。 Here is the code: 这是代码:

/**
 * Function name: parseArguments
 * Description:
 *    Determine what options or arguments user used
 *    Command-line options:
 *   [-h]    : Show help information
 *   [-n] num: Determine number of threads
 *   file1   : Choose first file
 *   file2   : Choose second file
 * Return value:
 *    0: If parsing successful
 *    exit: If error
 **/
static int parseArguments(int argc, char **argv, int* nthreads, char* file1, char* file2)
{
  int opt;
  int help=0;
  extern int optind;
  extern char * optarg;    // (global variable) command-line options

  while ((opt = getopt(argc, argv, "hn:")) != EOF)
  {
    switch (opt) {
      //Parse option -h, -n
      case 'n':
        *nthreads = atoi(optarg);
        break;
    case 'h':
        Usage();
        exit(1);
        break;
      default:
        fprintf(stderr, "Try 'mulvector -h' for more information\n");
        exit(1);
    }


    // parse file1 & file2 arguments
// THIS IS WHAT I'M ASKING
        if (optind < argc)
    {
        file1 = &argv[optind];
        optind++;
    }
    if (optind < argc)
        file2 = &argv[optind];
  }

  return 0;
}

The problem is that, after i called this function (in the main() function) and then exit this function (continue the main() function), the 2 variables file1 & file2 still keep their old values before executing the parseArguments function. 问题是,在我调用此函数(在main()函数中)然后退出此函数(继续main()函数)之后,两个变量file1和file2在执行parseArguments函数之前仍保持其旧值。 I'm trying to fix this but i get no result ... 我正在尝试解决此问题,但没有结果...

Hope you guys can help, thanks so much in advanced ! 希望你们能提供帮助,非常感谢!

NOTE: The type of file1 and file2 are char file1[1024] so i can't use char** as the arguments for the parseArguments function ! 注意: file1和file2的类型是char file1 [1024],所以我不能将char **用作parseArguments函数的参数!

C passes arguments by value. C按值传递参数。 The modifications that you make to file1 and file2 are therefore only modifications to the local copies of the pointers that exist inside the function. 因此,您对file1file2所做的修改仅是对函数内部存在的指针的本地副本的修改。 The caller does not see those changes. 呼叫者看不到那些更改。

You probably want to either: 您可能想要:

  1. Copy text to the buffers that file1 and file2 refer to, or 将文本复制到file1file2引用的缓冲区,或者
  2. Pass the addresses of file1 and file2 to the function and modify the values seen by the caller. file1file2的地址传递给该函数,并修改调用者看到的值。

Option 1 looks like this: 选项1如下所示:

static int parseArguments(..., char* file1, char* file2)
{
    ....
    strcpy(file1, argv[optind]);
    ....
    strcpy(file2, argv[optind]);
    ....
}

Of course, this is asking for buffer overrun. 当然,这是在要求缓冲区溢出。 So you would also be wise to pass the length of the buffer to allow the code to avoid that overrun, for example by using strncpy or strncat . 因此,明智的做法是传递缓冲区的长度,以使代码避免溢出,例如通过使用strncpystrncat There is a good discussion of the issue here: Why should you use strncpy instead of strcpy? 这里对此问题进行了很好的讨论: 为什么要使用strncpy而不是strcpy?

Option 2 looks like this: 选项2如下所示:

static int parseArguments(..., char** file1, char** file2)
{
    ....
    *file1 = &argv[optind];
    ....
    *file2 = &argv[optind];
    ....
}
file1 = &argv[optind];

If you want to modify a pointer object, you have to pass to the function a pointer to a pointer and not just the pointer object value. 如果要修改指针对象,则必须将指向指针的指针传递给函数,而不仅仅是指针对象的值。

That is: 那是:

char **file1, char **file2

instead of 代替

char* file1, char* file2

C is pass-by-value, even for pointers. C是传递值,即使对于指针也是如此。 If you want to change a pointer, you need to pass in a pointer to it and then dereference the pointer to get to the variable behind it. 如果要更改指针,则需要传递一个指向它的指针,然后取消对该指针的引用以获取其背后的变量。

That means a double pointer to your function: 这意味着指向您的函数的双重指针:

static int parseArguments (int      argc,
                           char   **argv,
                           int     *nthreads,
                           char   **pFile1,
                           char   **pFile2)

and calling it with the addresses of those pointers: 并使用这些指针的地址进行调用:

char *somePtr, *otherPtr;
int rc = parseArguments (..., &somePtr, &otherPtr);

It also means dereferencing within the function itself, such as: 它还意味着在函数本身内取消引用,例如:

*pFile1 = &argv[optind];

It would actually be quite easy it would be for ISO to fix this problem that people keep having with C having to emulate pass-by-reference. 对于ISO来说,要解决这个问题,实际上是很容易的,因为人们不得不继续使用C来模拟按引用传递。

They could simply add a special marker for variables in function prototypes to indicate that they're pass-by-reference and, therefore, access to them would be indirect in the function. 他们可以简单地为函数原型中的变量添加一个特殊标记,以指示它们是按引用传递的,因此,对它们的访问将在函数中是间接的。

Whether this actually ever happens, it's hard to say. 是否真的发生过,这很难说。


As to your comment: 关于您的评论:

NOTE: The type of file1 and file2 are char file1[1024] so I can't use char** as the arguments for the parseArguments function! 注意:file1和file2的类型是char file1 [1024],所以我不能将char **用作parseArguments函数的参数!

If you want to pass in a buffer address that can't be modified, then you have to shift memory into that buffer (and ignore my comments above), such as with: 如果要传递一个不能修改的缓冲区地址,则必须将内存移入该缓冲区(并忽略上面的注释),例如:

strcpy (file1, argv[optind]);

although you may want to either check the length beforehand to prevent buffer overflow, or use a safer bounds-checking memory copying function. 尽管您可能需要事先检查长度以防止缓冲区溢出,或者使用更安全的边界检查内存复制功能。

Because you change addresses of pointers, unstead of values. 因为您更改指针的地址,而不是值。

You have to ways: 您必须采取以下方式:

  1. Get variables by link (char*& file1, char*& file2). 通过链接获取变量(char *&file1,char *&file2)。
  2. Get them by pointer (char** file1, char** file2), but you shoul call your function like parseArguments(..., &charPointer1, &charPointer2) 通过指针(char ** file1,char ** file2)获取它们,但是您应该像parseArguments(..., &charPointer1, &charPointer2)那样调用函数

If file1 and file2 point to valid memory, copy the contents of the memory where argc 's elements point to, to where file1 and file2 points to, but assigning argc`'s elements' addresses. 如果file1file2点到有效的内存,复制内存在内容argc的元素指向,到file1和文件2 points to, but assigning argc`的元素的地址。

To do so replace the assignment 为此,请替换作业

file1 = &argv[optind];

by a copy operation 通过复制操作

strcpy(file1, argv[optind]);

However doing so is risky as inside parseArgument() it isn't know how much memory hab been assigned to file and file2 . 但是这样做是有风险的,因为在parseArgument()内部,它不知道为filefile2分配了多少内存。

To get around this pass in to parseArguments also those sizes like this: 为了绕过这个传递到parseArguments那些大小,如下所示:

static int parseArguments(int argc, char **argv, int* nthreads, 
  char* file1, size_t size1, 
  char* file2, size_t size2)
{
  ...
  memset(file1, 0, size1);
  strncpy(file1, argv[optind], size1 - 1);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用函数对char *数组进行突变,但是在函数退出后字符串值会更改。 - Mutating array of char* using a function but string values change after function exit. 为什么退出此函数后传递给指针参数的指针变量的值没有变化? - Why didn't the value of pointer variable passed to pointer argument change after exiting this function? 将char **传递给函数,是否不更改其值,还是呢? - Passing char** into a function , doesn't change its values , or does it ? 这段代码没有抛出异常或退出,而是无限运行,为什么? - This code didn't throw an exception or exit but runs infinitely why? 为什么最后一个'printf' function 没有执行? - Why the last 'printf' function didn't execute? 为什么不字符 newWord[45]; 在像 char newWord[45] = &quot;&quot;; 这样的函数开始时有“干净”的值; 做? - why doesn´t char newWord[45]; have "clean" values at the start of a function like char newWord[45] = ""; does? 为什么不打印? - Why it didn't print? 为什么gcc没有为此函数决定是否为inline-or-not? - why didn't gcc decide inline-or-not for me for this function? 在 function 中使用后无法打印字符 - Can't print char after using it in a function 为什么没有-O3 GCC优化内联这个功能? - Why didn't -O3 GCC Optimization inline this function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM