简体   繁体   English

是否使用指向指针概念的指针进行冒泡排序?

[英]Applying bubble sort using pointer to pointer concept?

I am sorting an array alphabetically using bubble sort while applying the pointer to pointer concept. 我在将指针应用于指针概念时使用冒泡排序按字母顺序对数组进行排序。 My program crashes when I use strcpy function to swap address of array *b[4] using pointer to pointer **p[4], apart from that the program works fine. 当我使用strcpy函数使用指向指针** p [4]的指针交换数组* b [4]的地址时,我的程序崩溃了,除此之外该程序还可以正常工作。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
 {
   char a[][10]={"milk","eggs","bread","cheese"};
   char *b[4],**p[4],*temp;
   int length[4];
   int i,j;

   for(i=0;i<4;i++)
   {
      length[i]=strlen(a[i]);
      b[i]=(char *)calloc(length[i],sizeof(char));
      strcpy(b[i],a[i]);
      p[i]=&b[i];
    }

  for(j=0;j<4;j++)
   {
     for(i=0; i<3-j; i++)
      {
        if(strcmp(*p[i],*p[i+1])>0)
          { /*         
            strcpy(temp,*p[i]);    This is the part of the code where the  
            strcpy(*p[i],*p[i+1]); program crashes, can someone please point            
            strcpy(*p[i+1],temp);  out the logical flaw
             */
          }
       }
    }  

  for(i=0;i<4;i++)
   {
    puts(*p[i]);
   }  


}

The reason your program crashes is that you are trying to copy the content of a C string into an uninitialized pointer temp , causing undefined behavior. 程序崩溃的原因是,您试图将C字符串的内容复制到未初始化的指针temp ,从而导致未定义的行为。

Even if you fix this by supplying a buffer of appropriate length for the temp , you would get undefined behavior on copying longer strings into space allocated for shorter strings (eg when copying "cheese" into the space that has been allocated for "eggs" ). 即使通过为temp提供适当长度的缓冲区来解决此问题,将较长的字符串复制到为较短的字符串分配的空间中时,也会得到不确定的行为(例如,将"cheese"复制到已为"eggs"分配的空间中) 。 Moreover, your current implementation currently has undefined behavior, too, because it fails to allocate enough space to accommodate null terminator of your strings. 此外,当前的实现目前也具有未定义的行为,因为它无法分配足够的空间来容纳字符串的空终止符。

A proper way of fixing this is to swap pointers, rather than using them to copy the content. 解决此问题的一种正确方法是交换指针,而不是使用它们来复制内容。

In strcpy(temp,*p[i]) , temp is expected to point to memory into which the string should be copied. strcpy(temp,*p[i])temp预期指向应将字符串复制到的内存。 You never initialized temp , causing undefined behaviour. 您从未初始化temp ,从而导致未定义的行为。

But as you mentioned, all you need is to copy the pointer. 但是正如您提到的,您所要做的就是复制指针。

temp = p[i];
p[i] = p[i+1];
p[i+1] = temp;

Cleaned up solution: 清理解决方案:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
   const char *a[] = { "milk", "eggs", "bread", "cheese" };
   size_t n = sizeof(a)/sizeof(a[0]);

   const char** p;
   { /* Make p a shallow copy of a so that we don't change a */
      p = malloc(n * sizeof(char*));

      {
         size_t i;
         const char** src = a;
         const char** dst = p;
         for (i=n; i--; )
            *(dst++) = *(src++);
      }
   }

   { /* Sort p using bubble sort */
      size_t i;
      int swapped = 1;
      while (swapped) {
         swapped = 0;
         for (i=0; i<n-1; ++i) {
            if (strcmp(p[i], p[i+1]) > 0) {
               const char* temp = p[i];
               p[i] = p[i+1];
               p[i+1] = temp;
               swapped = 1;
            }
         }
      }
   }

   {
      size_t i;
      for (i=0; i<n; ++i)
         puts(p[i]);
   }

   free(p);
   return 0;
}

The problem is here 问题在这里

 for(i=0; i<3-j; i++)

j will iterate till it is less than 4, that means i will iterate till it is less than -1? j将迭代直到小于4,这意味着我将迭代直到小于-1?

  1. i started from 0 and it is incremented by one. 我从0开始,并且递增1。

  2. array index can never be equal to -1(because it starts from 0). 数组索引永远不能等于-1(因为它从0开始)。

also, change the above line to this 另外,将上面的行更改为此

 for(i=0; i<(j); i++)

the code is fine. 代码很好。

I'm not sure whether your desire to allocate and copy is for purpose of simple exercise, but in approaching the problem that way you wildly over-complicate what should be a simple pointer-swap to sort a . 我不知道你的分配和复制的愿望是简单的锻炼目的,但在接近疯狂的问题,这样你过分复杂化应该是什么简单的指针交换排序a For example, why declare a as a 2D array of char instead of an array of pointers to char (eg char *a[] = {....} )? 例如,为什么a a声明为char2D数组而不是char 的指针数组 (例如char *a[] = {....} )?

By declaring a as an array of pointers, you simply need to swap pointers in your sort -- no allocation or copying required, eg 通过将a声明为指针数组,您只需要交换排序中的指针-无需分配或复制,例如

#include<stdio.h>
#include<string.h>

int main (void) {

    char *a[] = {"milk","eggs","bread","cheese"};
    size_t n = sizeof a / sizeof *a, i, j;

    for(j = 0; j < n; j++)
        for(i = 0; i < n - 1 - j; i++)
            if(strcmp(a[i], a[i+1]) > 0) {        
                char *tmp = a[i];  
                a[i] = a[i+1];            
                a[i+1] = tmp;
            }

    for (i = 0; i < n; i++)
        printf ("a[%zu] : %s\n", i, a[i]);

    return 0;
}

Compile VS (cl.exe) 编译VS(cl.exe)

>cl /nologo /Wall /wd4710 /Ox /Foobj/bsarrayptr /Febin/bsarrayptr /Tc bsarrayptrs.c

Compile gcc 编译gcc

$ gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o bin/bsarrayptr bsarrayptrs.c

Example Use/Output 使用/输出示例

C:\Users\david\Documents\dev\src-c\tmp>bin\bsarrayptr.exe
a[0] : bread
a[1] : cheese
a[2] : eggs
a[3] : milk

If your intent was just to perform an exercise using additional levels of indirection, copying and allocation, that's fine, but if you intent was to handle a alphabetical sort of a , then simply swapping pointers is a much more efficient approach. 如果您的目的只是为了进行间接使用,复制和分配的附加级别的演习,这很好,但如果你的意图是处理一个字母排序的a ,后来干脆换指针是一个更有效的方法。

Look things over and let me know if you have further questions. 仔细检查一下,如果您还有其他问题,请告诉我。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM