【问题标题】:Pointer initialization and string manipulation in CC中的指针初始化和字符串操作
【发布时间】:2010-12-01 12:15:42
【问题描述】:
  1. 我有这个函数,它从 main() 调用了大约 1000 次。当我使用 malloc() 在这个函数中初始化一个指针时,会发生段错误,可能是因为我在离开函数之前没有 free() 它。现在,我在返回 main 之前尝试了 free() 指针,但它没有用,最终发生了 seg 错误。
    1. 上述场景是一回事,我如何初始化双指针 (**ptr) 和指向指针数组的指针 (*ptr[])?
    2. 有没有办法将一个字符串(它是一个 char 数组)复制到一个 char 指针数组中。 字符 arr[]; (假设有五十个这样的数组) 字符 *ptr_arr[50];现在我想在 *ptr_arr[] 中指向每个这样的 char arr[] 如何在这里初始化 char *ptr_arr[]?
    3. C 中未初始化的指针有什么影响?
    4. strcpy() 是自己附加 '\0' 还是我们必须手动附加? strcpy() 与 strncpy() 相比有多安全?与 strcat() 和 strncat() 一样。

谢谢。

【问题讨论】:

  • 提供源代码通常很有帮助。
  • 请发布您的失败代码,以便我们向您展示您出错的地方。
  • 最好使用minimal 的源代码示例。最小的一点就是完整的问题。
  • 如果您使用的是 Linux 或 OSX,我建议您通过 Valgrind/memcheck 运行您的代码以跟踪 1。

标签: c pointers string segmentation-fault


【解决方案1】:
  1. Segfault 可能由多种原因引起。您是否检查 malloc 之后的指针(如果它为 NULL)?逐行逐行查看代码的确切位置(并提出一个包含更多细节和代码的单独问题)

  2. 您似乎不了解 C 中指针和数组的关系。首先,指向指针数组的指针定义为 type***type**[]。在实践中,只有两次间接指针是有用的。不过,你可以有这样的东西,只需取消引用指针足够多次并进行实​​际的内存分配。

  3. 这很混乱。应该是一个单独的问题。

  4. 它们很可能会使您的程序崩溃,但这是未定义的,因此您无法确定。它们可能具有已使用的内存“插槽”的地址,因此可能存在您甚至没有注意到的错误。

【讨论】:

    【解决方案2】:

    根据您的问题,我的建议是谷歌“C 中的指针”并阅读一些教程以了解指针是什么以及如何使用它们 - 在 SO 答案中需要重复很多内容让你快速上手。

    排名前两位的是herehere

    【讨论】:

    • 但关键是,这是人们在谷歌上搜索编程问题的网站。如果每个答案都是“Google it”,我们就没有建立网站的知识库。也就是说,操作员同时提出 5 个相关问题这一事实并没有帮助。
    • 许多问题可以通过谷歌搜索解决,但有时您确实需要请“已经做过”的其他人来提供帮助。有时您只是不知道在搜索框中输入什么。但我认为期望人们在要求 SO 社区在此处输入这些网站的内容之前尝试研究一些内容是合理的。另外,我无法比已经有描述的百万零一个网站更好地解释指针,所以我认为“看这里”是一个完全合理的初始响应。
    【解决方案3】:

    如果不看一些代码就很难回答你的第一个问题——分段错误很难追踪,而看到代码会更直接。

    双指针并不比单指针更特殊,因为它们背后的概念是相同的。比如……

    char * c = malloc(4);
    char **c = &c;
    

    我不太确定 c) 在问什么,但要回答你的最后一个问题,未初始化的指针在 C 中具有未定义的操作,即。你不应该依赖任何特定的结果。

    编辑:自从我回复后,您似乎添加了一个问题...

    strcpy(..) 确实会将源字符串的空终止符复制到目标字符串。

    【讨论】:

      【解决方案4】:

      对于“a”部分,也许这会有所帮助:

      void myfunction(void) {
        int * p = (int *) malloc (sizeof(int));
        free(p);
      }
      
      int main () {
        int i;
        for (i = 0; i < 1000; i++)
          myfunction();
      
        return 0;
      }
      

      Here 很好地介绍了斯坦福大学的指针。

      【讨论】:

        【解决方案5】:

        指针是一种特殊类型的变量,它保存另一个变量的地址或位置。指针通过记录存储它们的位置来指向这些位置。通过记录变量存储的地址可以找到指向变量的指针。总是可以使用特殊的 & 运算符在 C 中找到一块存储的地址。例如:如果location 是一个浮点型变量,那么很容易找到指向它的指针location_ptr

        float location;
        float *location_ptr,*address;
        
        location_ptr = &(location);
        

         address = &(location);
        

        指针的声明起初看起来有点奇怪。变量名前面的星 * 符号是 C 将该变量声明为指针的方式。上面的四行创建了两个相同的指针,指向一个名为 location 的浮点变量,其中一个称为location_ptr,另一个称为address。关键是指针只是一个记录变量地址的地方,所以它们其实是一回事。

        指针是一束包含两部分的信息。一部分是内存段的开头地址,该地址包含所指向的任何内容。另一部分是指针指向开头的值的类型。这告诉计算机在开始读取后有多少内存以及如何解释它。因此,如果指针是 int 类型,则返回的内存段将是四个字节长(32 位)并被解释为整数。在函数的情况下,类型是函数将返回的值的类型,尽管地址是函数可执行文件的开头地址。

        还可以在http://www.jnucode.blogspot.com 上获得更多关于 C/C++ 编程的教程

        【讨论】:

          【解决方案6】:

          您添加了一个关于 strcpy/strncpy 的附加问题。

          strcpy 实际上更安全。 它复制一个以 nul 结尾的字符串,并将 nul 终止符添加到副本中。即你得到一个与原始字符串完全相同的副本。

          另一方面,strncpy 有两种不同的行为:

          • 如果源字符串的长度少于 'n' 个字符,它就像 strcpy,nul 终止副本
          • 如果源字符串的长度大于或等于“n”个字符,则它会在到达“n”时停止复制,并保留字符串未终止。因此,必须始终对结果字符串进行 nul 终止以确保它仍然有效:
          字符目的地[123]; strncpy(目标,源,123); 目的地[122] = '\0';

          【讨论】:

            猜你喜欢
            • 2017-11-03
            • 2011-06-17
            • 2010-12-12
            • 1970-01-01
            • 2014-09-26
            • 2017-01-30
            • 2016-07-01
            • 2015-08-03
            相关资源
            最近更新 更多